3 use Test::Deep qw(cmp_deeply cmp_bag);
 
   8 use_ok 'Support::TestSetup';
 
   9 use SL::DATEV qw(:CONSTANTS);
 
  10 use SL::Dev::ALL qw(:ALL);
 
  11 use List::Util qw(sum);
 
  12 use SL::DB::Buchungsgruppe;
 
  16 Support::TestSetup::login();
 
  20 my $dbh = SL::DB->client->dbh;
 
  22 my $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || die "No accounting group for 7\%";
 
  23 my $bank            = SL::DB::Manager::Chart->find_by(description => 'Bank')                 || die 'Can\'t find chart "Bank"';
 
  24 my $date            = DateTime->new(year => 2017, month =>  1, day => 1);
 
  25 my $payment_date    = DateTime->new(year => 2017, month =>  1, day => 5);
 
  26 my $gldate          = DateTime->new(year => 2017, month =>  2, day => 9); # simulate bookings for Jan being made in Feb
 
  27 my $department      = create_department(description => 'Kostenstelle DATEV-Schnittstelle 2018');
 
  28 my $project         = create_project(projectnumber => 2017, description => 'Crowd-Funding September 2017');
 
  29 my $customer        = new_customer(customernumber => '10001', name => 'Testcustomer')->save;
 
  30 my $vendor          = new_vendor(vendornumber => '70001', name => 'Testvendor')->save;
 
  32 my $part1 = new_part(partnumber => '19', description => 'Part 19%')->save;
 
  35   description        => 'Part 7%',
 
  36   buchungsgruppen_id => $buchungsgruppe7->id,
 
  39 my $invoice = create_sales_invoice(
 
  40   invnumber    => "Þ sales ¥& invöice",
 
  41   customer     => $customer,
 
  44   intnotes     => 'booked in February',
 
  47   invoiceitems => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
 
  48                     create_invoice_item(part => $part2, qty => 10, sellprice => 50),
 
  50   department_id    => $department->id,
 
  51   globalproject_id => $project->id,
 
  53 $invoice->pay_invoice(chart_id      => $bank->id,
 
  54                       amount        => $invoice->open_amount,
 
  55                       transdate     => $payment_date->to_kivitendo,
 
  59 my $datev1 = SL::DATEV->new(
 
  60   dbh        => $invoice->db->dbh,
 
  61   trans_id   => $invoice->id,
 
  64 $datev1->generate_datev_data;
 
  66 my @data_datev   = sort { $a->{umsatz} <=> $b->{umsatz} } @{ $datev1->generate_datev_lines() };
 
  67 cmp_deeply \@data_datev, [
 
  69                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
 
  70                                            'buchungstext' => 'Testcustomer',
 
  71                                            'datum'        => '01.01.2017',
 
  72                                            'gegenkonto'   => '8400',
 
  74                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
 
  75                                            'kost2'        => 'Crowd-Funding September 2017',
 
  81                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
 
  82                                            'buchungstext' => 'Testcustomer',
 
  83                                            'datum'        => '01.01.2017',
 
  84                                            'gegenkonto'   => '8300',
 
  86                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
 
  87                                            'kost2'        => 'Crowd-Funding September 2017',
 
  93                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
 
  94                                            'buchungstext' => 'Testcustomer',
 
  95                                            'buchungstext' => 'Testcustomer',
 
  96                                            'datum'        => '05.01.2017',
 
  97                                            'gegenkonto'   => '1400',
 
  99                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
 
 100                                            'kost2'        => 'Crowd-Funding September 2017',
 
 105                                        ], "trans_id datev check ok";
 
 108 $datev1->generate_datev_data;
 
 109 # TODO for cmp_deeply we need to sort the incoming data structure (see below)
 
 110 cmp_bag $datev1->generate_datev_lines, [
 
 112                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
 
 113                                            'buchungstext' => 'Testcustomer',
 
 114                                            'datum'        => '01.01.2017',
 
 115                                            'gegenkonto'   => '8400',
 
 116                                            'konto'        => $customer->customernumber,
 
 117                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
 
 118                                            'kost2'        => 'Crowd-Funding September 2017',
 
 124                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
 
 125                                            'buchungstext' => 'Testcustomer',
 
 126                                            'datum'        => '01.01.2017',
 
 127                                            'gegenkonto'   => '8300',
 
 128                                            'konto'        => $customer->customernumber,
 
 129                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
 
 130                                            'kost2'        => 'Crowd-Funding September 2017',
 
 136                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
 
 137                                            'buchungstext' => 'Testcustomer',
 
 138                                            'datum'        => '05.01.2017',
 
 139                                            'gegenkonto'   => $customer->customernumber,
 
 141                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
 
 142                                            'kost2'        => 'Crowd-Funding September 2017',
 
 147                                        ], "trans_id datev check use_pk ok";
 
 150 my $startdate = DateTime->new(year => 2017, month =>  1, day =>  1);
 
 151 my $enddate   = DateTime->new(year => 2017, month => 12, day => 31);
 
 153 # check conversion to csv
 
 154 $datev1->from($startdate);
 
 155 $datev1->to($enddate);
 
 156 # reset use_pk for csv_buchungsexport
 
 158 $datev1->generate_datev_data;
 
 161 my $datev_csv = SL::DATEV::CSV->new(datev_lines  => $datev1->generate_datev_lines,
 
 164                                     locked       => $datev1->locked,
 
 169 # we need sort, because pay_invoice is not acc_trans_id order safe
 
 170 my @data_csv    = sort { $a->[0] cmp $b->[0] } @{ $datev_csv->lines };
 
 171 # warnings should be undef -> no array elements at all
 
 172 is(scalar @{ $datev_csv->warnings }, 0);
 
 175 cmp_deeply($data_csv[1], [ '535', 'S', 'EUR', '', '', '', '1400', '8300', '', '0101', "\x{de} sales \x{a5}& i",
 
 176                      '', '', 'Testcustomer', '', '', '', '', '', '', '', '',
 
 177                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 178                      '', 'Kostenst', 'Crowd-Fu', '', '', '', '', '', '', '', '',
 
 179                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 180                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 181                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 182                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 183                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 184                      '', '', '1', '', '', '', '', '', '' ]
 
 187 cmp_deeply($data_csv[0], [ '249,9', 'S', 'EUR', '', '', '', '1400', '8400', '', '0101', "\x{de} sales \x{a5}& i",
 
 188                      '', '', 'Testcustomer', '', '', '', '', '', '', '', '',
 
 189                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 190                      '', 'Kostenst', 'Crowd-Fu', '', '', '', '', '', '', '', '',
 
 191                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 192                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 193                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 194                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 195                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 196                      '', '', '1', '', '', '', '', '', '' ]
 
 198 cmp_deeply($data_csv[2], [ '784,9', 'S', 'EUR', '', '', '', '1200', '1400', '', '0501', "\x{de} sales \x{a5}& i",
 
 199                      '', '', 'Testcustomer', '', '', '', '', '', '', '', '',
 
 200                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 201                      '', 'Kostenst', 'Crowd-Fu', '', '', '', '', '', '', '', '',
 
 202                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 203                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 204                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 205                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 206                      '', '', '', '', '', '', '', '', '', '', '', '', '',
 
 207                      '', '', '1', '', '', '', '', '', '' ]
 
 209 my $march_9 = DateTime->new(year => 2017, month =>  3, day => 9);
 
 210 my $invoice2 = create_sales_invoice(
 
 211   invnumber    => "2 sales invoice",
 
 212   customer     => $customer,
 
 215   intnotes     => 'booked in March',
 
 218   invoiceitems => [ create_invoice_item(part => $part1, qty =>  6, sellprice => 70),
 
 219                     create_invoice_item(part => $part2, qty => 20, sellprice => 50),
 
 223 my $credit_note = create_credit_note(
 
 224   invnumber    => 'Gutschrift 34',
 
 225   customer     => $customer,
 
 228   intnotes     => 'booked in February',
 
 231   invoiceitems => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
 
 232                     create_invoice_item(part => $part2, qty => 10, sellprice => 50),
 
 236 my $datev = SL::DATEV->new(
 
 241 $datev->generate_datev_data(from_to => $datev->fromto);
 
 242 my $datev_lines = $datev->generate_datev_lines;
 
 243 my $umsatzsumme = sum map { $_->{umsatz} } @{ $datev_lines };
 
 244 cmp_ok($::form->round_amount($umsatzsumme,2), '==', 3924.5, "Sum of all bookings ok");
 
 246 $datev->generate_datev_data(use_pk => 1, from_to => $datev->fromto);
 
 247 $datev_lines = $datev->generate_datev_lines;
 
 249 note('testing purchase invoice');
 
 250 my $purchase_invoice = create_ap_transaction(
 
 257   itime       => $date, # make sure itime is 1.1., as gldatefrom tests for itime!
 
 261                      chart  => SL::DB::Manager::Chart->find_by(accno => '3400'),
 
 265                      chart  => SL::DB::Manager::Chart->find_by(accno => '3300'),
 
 271 $datev1 = SL::DATEV->new(
 
 272   dbh        => $purchase_invoice->db->dbh,
 
 273   trans_id   => $purchase_invoice->id,
 
 276 $datev1->generate_datev_data;
 
 277 cmp_deeply $datev1->generate_datev_lines, [
 
 279                                           'belegfeld1'             => 'ap1',
 
 280                                           'buchungstext'           => 'Testvendor',
 
 281                                           'datum'                  => '01.01.2017',
 
 282                                           'gegenkonto'             => '1600',
 
 291                                           'belegfeld1'             => 'ap1',
 
 292                                           'buchungstext'           => 'Testvendor',
 
 293                                           'datum'                  => '01.01.2017',
 
 294                                           'gegenkonto'             => '1600',
 
 302                                        ], "trans_id datev check purchase_invoice ok";
 
 304 $datev1->generate_datev_data;
 
 305 cmp_deeply $datev1->generate_datev_lines, [
 
 307                                           'belegfeld1'             => 'ap1',
 
 308                                           'buchungstext'           => 'Testvendor',
 
 309                                           'datum'                  => '01.01.2017',
 
 310                                           'gegenkonto'             => $vendor->vendornumber,
 
 319                                           'belegfeld1'             => 'ap1',
 
 320                                           'buchungstext'           => 'Testvendor',
 
 321                                           'datum'                  => '01.01.2017',
 
 322                                           'gegenkonto'             => $vendor->vendornumber,
 
 330                                        ], "trans_id datev check purchase_invoice use_pk ok";
 
 332 note('testing gldatefrom');
 
 333 # test an order with transdate in january, but that was booked in march
 
 334 # gldatefrom in DATEV.pm checks for itime, not gldate!!!
 
 335 $datev = SL::DATEV->new(
 
 338   to         => DateTime->new(year => 2017, month => 01, day => 31),
 
 341 $::form               = Support::TestSetup->create_new_form;
 
 342 $::form->{gldatefrom} = DateTime->new(year => 2017, month => 3, day => 1)->to_kivitendo;
 
 344 $datev->generate_datev_data(from_to => $datev->fromto);
 
 345 $datev_lines = $datev->generate_datev_lines;
 
 346 $umsatzsumme = sum map { $_->{umsatz} } @{ $datev_lines };
 
 347 cmp_ok($umsatzsumme, '==', 1569.8, "Sum of bookings made after March 1st (only invoice2) ok");
 
 349 $::form->{gldatefrom} = DateTime->new(year => 2017, month => 5, day => 1)->to_kivitendo;
 
 350 $datev->generate_datev_data(from_to => $datev->fromto);
 
 351 cmp_deeply $datev->generate_datev_lines, [], "no bookings for January made after May 1st: ok";
 
 357   SL::DB::Manager::AccTransaction->delete_all(all => 1);
 
 358   SL::DB::Manager::InvoiceItem->delete_all(   all => 1);
 
 359   SL::DB::Manager::Invoice->delete_all(       all => 1);
 
 360   SL::DB::Manager::PurchaseInvoice->delete_all(all => 1);
 
 361   SL::DB::Manager::Customer->delete_all(      all => 1);
 
 362   SL::DB::Manager::Part->delete_all(          all => 1);
 
 363   SL::DB::Manager::Project->delete_all(       all => 1);
 
 364   SL::DB::Manager::Department->delete_all(    all => 1);
 
 365   SL::DATEV->clean_temporary_directories;