Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision e592e0bc

Von G. Richardson vor mehr als 4 Jahren hinzugefügt

  • ID e592e0bc4aaf7ce59e4d5eec9834cb430ab6a33f
  • Vorgänger 0fed2b9a
  • Nachfolger d41fb52a

Jahresabschluß - GLTransaction->post und Tests

Der YearEnd Controller nutzt nun GLTransaction->post, damit muß man die
acc_trans-Einträge nicht mehr von Hand zusammenbauen, und die Buchungen
passieren automatisch als Transaktion, die Buchungen werden validiert
und es wird ein Historieneintrag erstellt.

Unterschiede anzeigen:

SL/Controller/YearEndTransactions.pm
49 49

  
50 50
  $self->_parse_form;
51 51

  
52

  
53 52
  eval {
54 53
    _year_end_bookings( start_date => $self->cb_startdate,
55 54
                        cb_date    => $self->cb_date,
......
66 65
                                               );
67 66

  
68 67
  my $html = $self->render('yearend/_charts', { layout  => 0 , process => 1, output => 0 },
69
                 charts          => $report_data,
70
                 profit_loss_sum => $profit_loss_sum,
71
               );
68
                           charts          => $report_data,
69
                           profit_loss_sum => $profit_loss_sum,
70
                          );
72 71
  return $self->js->flash('info', t8('Year-end bookings were successfully completed!'))
73 72
               ->html('#charts', $html)
74 73
               ->render;
......
105 104
                                               );
106 105

  
107 106
  $self->render('yearend/_charts', { layout  => 0 , process => 1 },
108
                 charts          => $report_data,
109
                 profit_loss_sum => $profit_loss_sum,
107
                charts          => $report_data,
108
                profit_loss_sum => $profit_loss_sum,
110 109
               );
111 110
}
112 111

  
......
121 120
  $self->cb_startdate($::locale->parse_date_to_object($self->get_balance_starting_date($self->cb_date)));
122 121

  
123 122
  die "cb_date must come after start_date" unless $self->cb_date > $self->cb_startdate;
124

  
125 123
}
126 124

  
127 125
sub _year_end_bookings {
......
140 138
                                                cb_date    => $cb_date,
141 139
                                               );
142 140

  
141
  # load all charts from report as objects and store them in a hash
142
  my @report_chart_ids = map { $_->{chart_id} } @{ $report_data };
143
  my %charts_by_id = map { ( $_->id => $_ ) } @{ SL::DB::Manager::Chart->get_all(where => [ id => \@report_chart_ids ]) };
144

  
143 145
  my @asset_accounts       = grep { $_->{account_type} eq 'asset_account' }       @{ $report_data };
144 146
  my @profit_loss_accounts = grep { $_->{account_type} eq 'profit_loss_account' } @{ $report_data };
145 147

  
......
174 176
      description    => 'Automatische SB-Buchungen Bestandskonten Soll für ' . $cb_date->year,
175 177
      ob_transaction => 0,
176 178
      cb_transaction => 1,
179
      taxincluded    => 0,
180
      transactions   => [],
177 181
    );
178 182
    my $asset_ob_debit_entry = SL::DB::GLTransaction->new(
179 183
      employee_id    => $employee_id,
......
182 186
      description    => 'Automatische EB-Buchungen Bestandskonten Haben für ' . $ob_date->year,
183 187
      ob_transaction => 1,
184 188
      cb_transaction => 0,
189
      taxincluded    => 0,
190
      transactions   => [],
185 191
    );
186 192
    my $asset_cb_credit_entry = SL::DB::GLTransaction->new(
187 193
      employee_id    => $employee_id,
......
190 196
      description    => 'Automatische SB-Buchungen Bestandskonten Haben für ' . $cb_date->year,
191 197
      ob_transaction => 0,
192 198
      cb_transaction => 1,
199
      taxincluded    => 0,
200
      transactions   => [],
193 201
    );
194 202
    my $asset_ob_credit_entry = SL::DB::GLTransaction->new(
195 203
      employee_id    => $employee_id,
......
198 206
      description    => 'Automatische EB-Buchungen Bestandskonten Soll für ' . $ob_date->year,
199 207
      ob_transaction => 1,
200 208
      cb_transaction => 0,
209
      taxincluded    => 0,
210
      transactions   => [],
201 211
    );
202
    $asset_cb_debit_entry->transactions([]);
203
    $asset_ob_debit_entry->transactions([]);
204
    $asset_cb_credit_entry->transactions([]);
205
    $asset_ob_credit_entry->transactions([]);
206 212

  
207 213
    foreach my $asset_account ( @asset_accounts ) {
208 214
      next if $asset_account->{amount_with_cb} == 0;
209

  
210
      # create cb and ob acc_trans entry here, but decide which gl entry to add it to later
211
      my $asset_cb_acc = SL::DB::AccTransaction->new(
212
        transdate      => $cb_date,
213
        ob_transaction => 0,
214
        cb_transaction => 1,
215
        chart_id       => $asset_account->{chart_id},
216
        chart_link     => $asset_account->{chart_link},
217
        tax_id         => 0,
218
        taxkey         => 0,
219
        amount         => - $asset_account->{amount_with_cb},
220
      );
221
      my $asset_ob_acc = SL::DB::AccTransaction->new(
222
        transdate      => $ob_date,
223
        ob_transaction => 1,
224
        cb_transaction => 0,
225
        chart_id       => $asset_account->{chart_id},
226
        chart_link     => $asset_account->{chart_link},
227
        tax_id         => 0,
228
        taxkey         => 0,
229
        amount         => $asset_account->{amount_with_cb},
230
      );
215
      my $ass_acc = $charts_by_id{ $asset_account->{chart_id} };
231 216

  
232 217
      if ( $asset_account->{amount_with_cb} < 0 ) {
233
        $debit_balance += $asset_account->{amount_with_cb};
234 218
        # $main::lxdebug->message(0, sprintf("adding accno %s with balance %s to debit", $asset_account->{accno}, $asset_account->{amount_with_cb}));
219
        $debit_balance += $asset_account->{amount_with_cb};
220

  
221
        $asset_cb_debit_entry->add_chart_booking(
222
          chart  => $ass_acc,
223
          credit => - $asset_account->{amount_with_cb},
224
          tax_id => 0
225
        );
226
        $asset_ob_debit_entry->add_chart_booking(
227
          chart  => $ass_acc,
228
          debit  => - $asset_account->{amount_with_cb},
229
          tax_id => 0
230
        );
235 231

  
236
        $asset_cb_debit_entry->add_transactions($asset_cb_acc);
237
        $asset_ob_debit_entry->add_transactions($asset_ob_acc);
238 232
      } else {
239 233
        # $main::lxdebug->message(0, sprintf("adding accno %s with balance %s to credit", $asset_account->{accno}, $asset_account->{amount_with_cb}));
240 234
        $credit_balance += $asset_account->{amount_with_cb};
241
        $asset_cb_credit_entry->add_transactions($asset_cb_acc);
242
        $asset_ob_credit_entry->add_transactions($asset_ob_acc);
235

  
236
        $asset_cb_credit_entry->add_chart_booking(
237
          chart  => $ass_acc,
238
          debit  => $asset_account->{amount_with_cb},
239
          tax_id => 0
240
        );
241
        $asset_ob_credit_entry->add_chart_booking(
242
          chart  => $ass_acc,
243
          credit  => $asset_account->{amount_with_cb},
244
          tax_id => 0
245
        );
243 246
      };
244 247
    };
245 248

  
246
    my $debit_cb_acc = SL::DB::AccTransaction->new(
247
      transdate      => $cb_date,
248
      ob_transaction => 0,
249
      cb_transaction => 1,
250
      chart_id       => $carry_over_chart->id,
251
      chart_link     => $carry_over_chart->link, # maybe leave chart_link empty?
252
      tax_id         => 0,
253
      taxkey         => 0,
254
      amount         => $debit_balance,
255
    );
256
    my $debit_ob_acc = SL::DB::AccTransaction->new(
257
      transdate      => $ob_date,
258
      ob_transaction => 1,
259
      cb_transaction => 0,
260
      chart_id       => $carry_over_chart->id,
261
      chart_link     => $carry_over_chart->link,
262
      tax_id         => 0,
263
      taxkey         => 0,
264
      amount         => - $debit_balance,
265
    );
266
    my $credit_cb_acc = SL::DB::AccTransaction->new(
267
      transdate      => $cb_date,
268
      ob_transaction => 0,
269
      cb_transaction => 1,
270
      chart_id       => $carry_over_chart->id,
271
      chart_link     => $carry_over_chart->link, # maybe leave chart_link empty?
272
      tax_id         => 0,
273
      taxkey         => 0,
274
      amount         => $credit_balance,
275
    );
276
    my $credit_ob_acc = SL::DB::AccTransaction->new(
277
      transdate      => $ob_date,
278
      ob_transaction => 1,
279
      cb_transaction => 0,
280
      chart_id       => $carry_over_chart->id,
281
      chart_link     => $carry_over_chart->link,
282
      tax_id         => 0,
283
      taxkey         => 0,
284
      amount         => - $credit_balance,
285
    );
286
    $asset_cb_debit_entry->add_transactions($debit_cb_acc);
287
    $asset_ob_debit_entry->add_transactions($debit_ob_acc);
288
    $asset_cb_credit_entry->add_transactions($credit_cb_acc);
289
    $asset_ob_credit_entry->add_transactions($credit_ob_acc);
249
    if ( $debit_balance ) {
250
      $asset_cb_debit_entry->add_chart_booking(
251
        chart  => $carry_over_chart,
252
        debit  => -1 * $debit_balance,
253
        tax_id => 0,
254
      );
255

  
256
      $asset_ob_debit_entry->add_chart_booking(
257
        chart  => $carry_over_chart,
258
        credit => -1 * $debit_balance,
259
        tax_id => 0,
260
      );
261
    };
262

  
263
    if ( $credit_balance ) {
264
      $asset_cb_credit_entry->add_chart_booking(
265
        chart  => $carry_over_chart,
266
        credit => $credit_balance,
267
        tax_id => 0,
268
      );
269
      $asset_ob_credit_entry->add_chart_booking(
270
        chart  => $carry_over_chart,
271
        debit  => $credit_balance,
272
        tax_id => 0,
273
      );
274
    };
290 275

  
291
    $asset_cb_debit_entry->save if scalar @{ $asset_cb_debit_entry->transactions } > 1;
292
    $asset_ob_debit_entry->save if scalar @{ $asset_ob_debit_entry->transactions } > 1;
293
    $asset_cb_credit_entry->save if scalar @{ $asset_cb_credit_entry->transactions } > 1;
294
    $asset_ob_credit_entry->save if scalar @{ $asset_ob_credit_entry->transactions } > 1;
276
    $asset_cb_debit_entry->post  if scalar @{ $asset_cb_debit_entry->transactions  } > 1;
277
    $asset_ob_debit_entry->post  if scalar @{ $asset_ob_debit_entry->transactions  } > 1;
278
    $asset_cb_credit_entry->post if scalar @{ $asset_cb_credit_entry->transactions } > 1;
279
    $asset_ob_credit_entry->post if scalar @{ $asset_ob_credit_entry->transactions } > 1;
295 280

  
296 281
    #######  profit-loss accounts #######
297 282
    # these only have a closing balance, the balance is transferred to the profit-loss account
......
301 286
    my $profit_loss_sum = sum map { $_->{amount_with_cb} }
302 287
                              grep { $_->{account_type} eq 'profit_loss_account' }
303 288
                              @{$report_data};
289
    $profit_loss_sum ||= 0;
304 290
    my $pl_chart;
305 291
    if ( $profit_loss_sum > 0 ) {
306 292
      $pl_chart = $profit_chart;
......
318 304
      description    => 'Automatische SB-Buchungen Erfolgskonten Soll für ' . $cb_date->year,
319 305
      ob_transaction => 0,
320 306
      cb_transaction => 1,
307
      taxincluded    => 0,
308
      transactions   => [],
321 309
    );
322 310
    my $pl_cb_credit_entry = SL::DB::GLTransaction->new(
323 311
      employee_id    => $employee_id,
......
326 314
      description    => 'Automatische SB-Buchungen Erfolgskonten Haben für ' . $cb_date->year,
327 315
      ob_transaction => 0,
328 316
      cb_transaction => 1,
317
      taxincluded    => 0,
318
      transactions   => [],
329 319
    );
330
    $pl_cb_debit_entry->transactions([]);
331
    $pl_cb_credit_entry->transactions([]);
332 320

  
333 321
    foreach my $profit_loss_account ( @profit_loss_accounts ) {
334 322
      # $main::lxdebug->message(0, sprintf("found chart %s with balance %s", $profit_loss_account->{accno}, $profit_loss_account->{amount_with_cb}));
323
      my $chart = $charts_by_id{ $profit_loss_account->{chart_id} };
335 324

  
336 325
      next if $profit_loss_account->{amount_with_cb} == 0;
337 326

  
338
      my $debit_cb_acc = SL::DB::AccTransaction->new(
339
        transdate      => $cb_date,
340
        ob_transaction => 0,
341
        cb_transaction => 1,
342
        chart_id       => $profit_loss_account->{chart_id},
343
        chart_link     => $profit_loss_account->{chart_link},
344
        tax_id         => 0,
345
        taxkey         => 0,
346
        amount         => - $profit_loss_account->{amount_with_cb},
347
      );
348
      my $credit_cb_acc = SL::DB::AccTransaction->new(
349
        transdate      => $cb_date,
350
        ob_transaction => 0,
351
        cb_transaction => 1,
352
        chart_id       => $profit_loss_account->{chart_id},
353
        chart_link     => $profit_loss_account->{chart_link},
354
        tax_id         => 0,
355
        taxkey         => 0,
356
        amount         => $profit_loss_account->{amount_with_cb},
357
      );
358
      if ( { $profit_loss_account->{amount_with_cb} < 0 } ) {
359
        $pl_debit_balance += $profit_loss_account->{amount_with_cb};
360
         $pl_cb_debit_entry->add_transactions($debit_cb_acc);
327
      if ( $profit_loss_account->{amount_with_cb} < 0 ) {
328
        $pl_debit_balance -= $profit_loss_account->{amount_with_cb};
329
        $pl_cb_debit_entry->add_chart_booking(
330
          chart  => $chart,
331
          tax_id => 0,
332
          credit => - $profit_loss_account->{amount_with_cb},
333
        );
361 334
      } else {
362 335
        $pl_credit_balance += $profit_loss_account->{amount_with_cb};
363
         $pl_cb_credit_entry->add_transactions($credit_cb_acc);
336
        $pl_cb_credit_entry->add_chart_booking(
337
          chart  => $chart,
338
          tax_id => 0,
339
          debit  => $profit_loss_account->{amount_with_cb},
340
        );
364 341
      };
365 342
    };
366 343

  
367
    $debit_cb_acc = SL::DB::AccTransaction->new(
368
      transdate      => $cb_date,
369
      ob_transaction => 0,
370
      cb_transaction => 1,
371
      chart_id       => $pl_chart->id,
372
      chart_link     => $pl_chart->link,
373
      tax_id         => 0,
374
      taxkey         => 0,
375
      amount         => $pl_debit_balance,
376
    );
377
    $credit_cb_acc = SL::DB::AccTransaction->new(
378
      transdate      => $cb_date,
379
      ob_transaction => 0,
380
      cb_transaction => 1,
381
      chart_id       => $pl_chart->id,
382
      chart_link     => $pl_chart->link,
383
      tax_id         => 0,
384
      taxkey         => 0,
385
      amount         => - $pl_credit_balance,
386
    );
387
    $pl_cb_debit_entry->add_transactions($debit_cb_acc);
388
    $pl_cb_credit_entry->add_transactions($credit_cb_acc);
344
    # $main::lxdebug->message(0, "pl_debit_balance  = $pl_debit_balance");
345
    # $main::lxdebug->message(0, "pl_credit_balance = $pl_credit_balance");
346

  
347
    $pl_cb_debit_entry->add_chart_booking(
348
      chart  => $pl_chart,
349
      tax_id => 0,
350
      debit  => $pl_debit_balance,
351
    ) if $pl_debit_balance;
352

  
353
    $pl_cb_credit_entry->add_chart_booking(
354
      chart  => $pl_chart,
355
      tax_id => 0,
356
      credit => $pl_credit_balance,
357
    ) if $pl_credit_balance;
389 358

  
390
    $pl_cb_debit_entry->save  if scalar @{ $pl_cb_debit_entry->transactions }  > 1;
391
    $pl_cb_credit_entry->save if scalar @{ $pl_cb_credit_entry->transactions } > 1;
359
    # printf("debit : %s -> %s\n", $_->chart->displayable_name, $_->amount) foreach @{ $pl_cb_debit_entry->transactions };
360
    # printf("credit: %s -> %s\n", $_->chart->displayable_name, $_->amount) foreach @{ $pl_cb_credit_entry->transactions };
361

  
362
    $pl_cb_debit_entry->post  if scalar @{ $pl_cb_debit_entry->transactions }  > 1;
363
    $pl_cb_credit_entry->post if scalar @{ $pl_cb_credit_entry->transactions } > 1;
392 364

  
393 365
    ######### profit-loss transfer #########
394 366
    # and finally transfer the new balance of the profit-loss account via the carry-over account
395 367
    # we want to use profit_loss_sum with cb!
396 368

  
397
    my $carry_over_cb_entry = SL::DB::GLTransaction->new(
398
      employee_id    => $employee_id,
399
      transdate      => $cb_date,
400
      reference      => 'SB ' . $cb_date->year,
401
      description    => sprintf('Automatische SB-Buchung für %s %s',
402
                                $profit_loss_sum >= 0 ? 'Gewinnvortrag' : 'Verlustvortrag',
403
                                $cb_date->year,
404
                               ),
405
      ob_transaction => 0,
406
      cb_transaction => 1,
407
    );
408
    my $carry_over_ob_entry = SL::DB::GLTransaction->new(
409
      employee_id    => $employee_id,
410
      transdate      => $ob_date,
411
      reference      => 'EB ' . $ob_date->year,
412
      description    => sprintf('Automatische EB-Buchung für %s %s',
413
                                $profit_loss_sum >= 0 ? 'Gewinnvortrag' : 'Verlustvortrag',
414
                                $ob_date->year,
415
                               ),
416
      ob_transaction => 1,
417
      cb_transaction => 0,
418
    );
419
    $carry_over_cb_entry->transactions([]);
420
    $carry_over_ob_entry->transactions([]);
369
    if ( $profit_loss_sum != 0 ) {
421 370

  
422
    my $carry_over_cb_acc_co = SL::DB::AccTransaction->new(
423
      transdate      => $cb_date,
424
      ob_transaction => 0,
425
      cb_transaction => 1,
426
      chart_id       => $carry_over_chart->id,
427
      chart_link     => $carry_over_chart->link,
428
      tax_id         => 0,
429
      taxkey         => 0,
430
      amount         => $profit_loss_sum,
431
    );
432
    my $carry_over_cb_acc_pl = SL::DB::AccTransaction->new(
433
      transdate      => $cb_date,
434
      ob_transaction => 0,
435
      cb_transaction => 1,
436
      chart_id       => $pl_chart->id,
437
      chart_link     => $pl_chart->link,
438
      tax_id         => 0,
439
      taxkey         => 0,
440
      amount         => - $profit_loss_sum,
441
    );
371
      my $carry_over_cb_entry = SL::DB::GLTransaction->new(
372
        employee_id    => $employee_id,
373
        transdate      => $cb_date,
374
        reference      => 'SB ' . $cb_date->year,
375
        description    => sprintf('Automatische SB-Buchung für %s %s',
376
                                  $profit_loss_sum >= 0 ? 'Gewinnvortrag' : 'Verlustvortrag',
377
                                  $cb_date->year,
378
                                 ),
379
        ob_transaction => 0,
380
        cb_transaction => 1,
381
        taxincluded    => 0,
382
        transactions   => [],
383
      );
384
      my $carry_over_ob_entry = SL::DB::GLTransaction->new(
385
        employee_id    => $employee_id,
386
        transdate      => $ob_date,
387
        reference      => 'EB ' . $ob_date->year,
388
        description    => sprintf('Automatische EB-Buchung für %s %s',
389
                                  $profit_loss_sum >= 0 ? 'Gewinnvortrag' : 'Verlustvortrag',
390
                                  $ob_date->year,
391
                                 ),
392
        ob_transaction => 1,
393
        cb_transaction => 0,
394
        taxincluded    => 0,
395
        transactions   => [],
396
      );
442 397

  
443
    $carry_over_cb_entry->add_transactions($carry_over_cb_acc_co);
444
    $carry_over_cb_entry->add_transactions($carry_over_cb_acc_pl);
445
    $carry_over_cb_entry->save if $profit_loss_sum != 0;
398
      my ($amount1, $amount2);
399
      if ( $profit_loss_sum < 0 ) {
400
        $amount1 = 'debit';
401
        $amount2 = 'credit';
402
      } else {
403
        $amount1 = 'credit';
404
        $amount2 = 'debit';
405
      };
446 406

  
447
    my $carry_over_ob_acc_co = SL::DB::AccTransaction->new(
448
      transdate      => $ob_date,
449
      ob_transaction => 1,
450
      cb_transaction => 0,
451
      chart_id       => $pl_chart->id,
452
      chart_link     => $pl_chart->link,
453
      tax_id         => 0,
454
      taxkey         => 0,
455
      amount         => $profit_loss_sum,
456
    );
457
    my $carry_over_ob_acc_pl = SL::DB::AccTransaction->new(
458
      transdate      => $ob_date,
459
      ob_transaction => 1,
460
      cb_transaction => 0,
461
      chart_id       => $carry_over_chart->id,
462
      chart_link     => $carry_over_chart->link,
463
      tax_id         => 0,
464
      taxkey         => 0,
465
      amount         => - $profit_loss_sum,
466
    );
407
      $carry_over_cb_entry->add_chart_booking(
408
        chart    => $carry_over_chart,
409
        tax_id   => 0,
410
        $amount1 => abs($profit_loss_sum),
411
      );
412
      $carry_over_cb_entry->add_chart_booking(
413
        chart    => $pl_chart,
414
        tax_id   => 0,
415
        $amount2 => abs($profit_loss_sum),
416
      );
417
      $carry_over_ob_entry->add_chart_booking(
418
        chart    => $carry_over_chart,
419
        tax_id   => 0,
420
        $amount2 => abs($profit_loss_sum),
421
      );
422
      $carry_over_ob_entry->add_chart_booking(
423
        chart    => $pl_chart,
424
        tax_id   => 0,
425
        $amount1 => abs($profit_loss_sum),
426
      );
427

  
428
      # printf("debit : %s -> %s\n", $_->chart->displayable_name, $_->amount) foreach @{ $carry_over_ob_entry->transactions };
429
      # printf("credit: %s -> %s\n", $_->chart->displayable_name, $_->amount) foreach @{ $carry_over_ob_entry->transactions };
467 430

  
468
    $carry_over_ob_entry->add_transactions($carry_over_ob_acc_co);
469
    $carry_over_ob_entry->add_transactions($carry_over_ob_acc_pl);
470
    $carry_over_ob_entry->save if $profit_loss_sum != 0;
431
      $carry_over_cb_entry->post if scalar @{ $carry_over_cb_entry->transactions } > 1;
432
      $carry_over_ob_entry->post if scalar @{ $carry_over_ob_entry->transactions } > 1;
433
    };
471 434

  
472 435
    my $consistency_query = <<SQL;
473 436
select sum(amount)
......
475 438
 where     (ob_transaction is true or cb_transaction is true)
476 439
       and (transdate = ? or transdate = ?)
477 440
SQL
478
     my ($sum) = my ($empty) = selectrow_query($::form, $db->dbh, $consistency_query,
479
                                               $cb_date,
480
                                               $ob_date
481
                                              );
441
    my ($sum) = selectrow_query($::form, $db->dbh, $consistency_query,
442
                                $cb_date,
443
                                $ob_date
444
                               );
482 445
     die "acc_trans transactions don't add up to zero" unless $sum == 0;
483 446

  
484 447
    1;
......
500 463
select c.id as chart_id,
501 464
       c.accno,
502 465
       c.description,
503
       c.link as chart_link,
504 466
       c.category,
505 467
       sum(a.amount) filter (where cb_transaction is false and ob_transaction is false) as amount,
506 468
       sum(a.amount) filter (where ob_transaction is true                             ) as ob_amount,
t/year_end/year_end.t
1
use strict;
2
use warnings;
3

  
4
use Test::More tests => 18;
5
use lib 't';
6
use utf8;
7

  
8
use Carp;
9
use Data::Dumper;
10
use Support::TestSetup;
11
use Test::Exception;
12
use SL::DBUtils qw(selectall_hashref_query);
13

  
14
use SL::DB::BankAccount;
15
use SL::DB::Chart;
16
use SL::DB::Invoice;
17
use SL::DB::PurchaseInvoice;
18

  
19
use SL::Dev::Record qw(create_ar_transaction create_ap_transaction create_gl_transaction);
20

  
21
use SL::Controller::YearEndTransactions;
22
  
23
Support::TestSetup::login();
24

  
25
clear_up();
26

  
27
# comments:
28

  
29
# * in the default test client the tax accounts are configured as I/E rather than A/L
30
# * also the default test client has the accounting method "cash" rather than "accrual"
31
#   (Ist-versteuerung, rather than Soll-versteuerung)
32

  
33
my $year = 2019;
34

  
35
note('configuring accounts');
36
my $bank_account = SL::DB::BankAccount->new(
37
  account_number  => '123',
38
  bank_code       => '123',
39
  iban            => '123',
40
  bic             => '123',
41
  bank            => '123',
42
  chart_id        => SL::DB::Manager::Chart->find_by(description => 'Bank')->id,
43
  name            => SL::DB::Manager::Chart->find_by(description => 'Bank')->description,
44
)->save;
45

  
46
my $profit_account = SL::DB::Manager::Chart->find_by(accno => '0890') //
47
                     SL::DB::Chart->new(
48
                       accno          => '0890',
49
                       description    => 'Gewinnvortrag vor Verwendung',
50
                       charttype      => 'A',
51
                       category       => 'Q',
52
                       link           => '',
53
                       taxkey_id      => '0',
54
                       datevautomatik => 'f',
55
                     )->save;
56

  
57
my $loss_account = SL::DB::Manager::Chart->find_by(accno => '0868') //
58
                   SL::DB::Chart->new(
59
                     accno          => '0868',
60
                     description    => 'Verlustvortrag vor Verwendung',
61
                     charttype      => 'A',
62
                     category       => 'Q',
63
                     link           => '',
64
                     taxkey_id      => '0',
65
                     datevautomatik => 'f',
66
                   )->save;
67

  
68
my $carry_over_chart = SL::DB::Manager::Chart->find_by(accno => 9000); 
69
my $income_chart     = SL::DB::Manager::Chart->find_by(accno => '8400'); # income 19%, taxkey 3
70
my $bank             = SL::DB::Manager::Chart->find_by(description => 'Bank');
71
my $cash             = SL::DB::Manager::Chart->find_by(description => 'Kasse');
72
my $privateinlagen   = SL::DB::Manager::Chart->find_by(description => 'Privateinlagen');
73
my $betriebsbedarf   = SL::DB::Manager::Chart->find_by(description => 'Betriebsbedarf'); 
74

  
75
my $dbh = SL::DB->client->dbh;
76
$dbh->do('UPDATE defaults SET carry_over_account_chart_id     = ' . $carry_over_chart->id);
77
$dbh->do('UPDATE defaults SET profit_carried_forward_chart_id = ' . $profit_account->id);
78
$dbh->do('UPDATE defaults SET loss_carried_forward_chart_id   = ' . $loss_account->id);
79

  
80

  
81
note('creating transactions');
82
my $ar_transaction = create_ar_transaction(
83
  taxincluded => 0,
84
  bookings    => [
85
                   {
86
                     chart  => $income_chart, # income 19%, taxkey 3
87
                     amount => 140,
88
                   }
89
                 ],
90
);
91
  
92
$ar_transaction->pay_invoice(
93
                              chart_id     => $bank_account->chart_id,
94
                              transdate    => DateTime->today_local->to_kivitendo,
95
                              amount       => $ar_transaction->amount,
96
                              payment_type => 'without_skonto',
97
                            );
98

  
99
my $ar_transaction2 = create_ar_transaction(
100
  taxincluded => 1,
101
  bookings    => [
102
                   {
103
                     chart  => $income_chart, # income 19%, taxkey 3
104
                     amount => 166.60,
105
                   }
106
                 ],
107
);
108

  
109
my $ap_transaction = create_ap_transaction(
110
  taxincluded => 0,
111
  bookings    => [
112
                   {
113
                     chart  => SL::DB::Manager::Chart->find_by( accno => '3400' ), # Wareneingang 19%, taxkey 9
114
                     amount => 100,
115
                   }
116
                 ],
117
);
118

  
119

  
120
gl_booking(40, "01.01.$year", 'foo', 'bar', $bank, $privateinlagen, 1, 0);
121

  
122
is(SL::DB::Manager::AccTransaction->get_all_count(                                ), 13, 'acc_trans transactions created ok');
123
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ ob_transaction => 1 ]),  2, 'acc_trans ob_transactions created ok');
124
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ cb_transaction => 1 ]),  0, 'no cb_transactions created ok');
125

  
126
is_deeply( &get_account_balances, 
127
           [
128
             {
129
               'accno'        => '1200',
130
               'account_type' => 'asset_account',
131
               'sum'          => '-206.60000'
132
             },
133
             {
134
               'accno'        => '1400',
135
               'account_type' => 'asset_account',
136
               'sum'          => '-166.60000'
137
             },
138
             {
139
               'accno'        => '1600',
140
               'account_type' => 'asset_account',
141
               'sum'          => '119.00000'
142
             },
143
             {
144
               'accno'        => '1890',
145
               'account_type' => 'asset_account',
146
               'sum'          => '40.00000'
147
             },
148
             {
149
               'accno'        => '1576',
150
               'account_type' => 'profit_loss_account',
151
               'sum'          => '-19.00000'
152
             },
153
             {
154
               'accno'        => '1776',
155
               'account_type' => 'profit_loss_account',
156
               'sum'          => '53.20000'
157
             },
158
             {
159
               'accno'        => '3400',
160
               'account_type' => 'profit_loss_account',
161
               'sum'          => '-100.00000'
162
             },
163
             {
164
               'accno'        => '8400',
165
               'account_type' => 'profit_loss_account',
166
               'sum'          => '280.00000'
167
             }
168
           ],
169
           'account balances before year_end bookings ok',
170
);
171

  
172
#  accno |    account_type     |    sum     
173
# -------+---------------------+------------
174
#  1200  | asset_account       | -206.60000
175
#  1400  | asset_account       | -166.60000
176
#  1600  | asset_account       |  119.00000
177
#  1890  | asset_account       |   40.00000
178
#  1576  | profit_loss_account |  -19.00000
179
#  1776  | profit_loss_account |   53.20000
180
#  3400  | profit_loss_account | -100.00000
181
#  8400  | profit_loss_account |  280.00000
182

  
183

  
184
note('running year-end transactions');
185
my $start_date = DateTime->new(year => $year, month => 1,  day => 1);  
186
my $cb_date    = DateTime->new(year => $year, month => 12, day => 31);
187
my $ob_date    = $cb_date->clone->add(days => 1);
188

  
189
SL::Controller::YearEndTransactions::_year_end_bookings( start_date => $start_date,
190
                                                         cb_date    => $cb_date,
191
                                                       );
192

  
193
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ cb_transaction => 1 ]), 14, 'acc_trans cb_transactions created ok');
194
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ ob_transaction => 1 ]), 10, 'acc_trans ob_transactions created ok');
195
is(SL::DB::Manager::GLTransaction->get_all_count( where => [ cb_transaction => 1 ]),  5, 'GL cb_transactions created ok');
196
is(SL::DB::Manager::GLTransaction->get_all_count( where => [ ob_transaction => 1 ]),  4, 'GL ob_transactions created ok');
197

  
198
my $final_account_balances = [
199
                               {
200
                                 'accno' => '0890',
201
                                 'amount' => undef,
202
                                 'amount_with_cb' => '0.00000',
203
                                 'cat' => 'Q',
204
                                 'cb_amount' => '0.00000',
205
                                 'ob_amount' => undef,
206
                                 'ob_next_year' => '214.20000',
207
                                 'type' => 'asset',
208
                                 'year_end_amount' => undef
209
                               },
210
                               {
211
                                 'accno' => '1200',
212
                                 'amount' => '-166.60000',
213
                                 'amount_with_cb' => '0.00000',
214
                                 'cat' => 'A',
215
                                 'cb_amount' => '-206.60000',
216
                                 'ob_amount' => '-40.00000',
217
                                 'ob_next_year' => '-206.60000',
218
                                 'type' => 'asset',
219
                                 'year_end_amount' => '-206.60000'
220
                               },
221
                               {
222
                                 'accno' => '1400',
223
                                 'amount' => '-166.60000',
224
                                 'amount_with_cb' => '0.00000',
225
                                 'cat' => 'A',
226
                                 'cb_amount' => '-166.60000',
227
                                 'ob_amount' => undef,
228
                                 'ob_next_year' => '-166.60000',
229
                                 'type' => 'asset',
230
                                 'year_end_amount' => '-166.60000'
231
                               },
232
                               {
233
                                 'accno' => '1600',
234
                                 'amount' => '119.00000',
235
                                 'amount_with_cb' => '0.00000',
236
                                 'cat' => 'L',
237
                                 'cb_amount' => '119.00000',
238
                                 'ob_amount' => undef,
239
                                 'ob_next_year' => '119.00000',
240
                                 'type' => 'asset',
241
                                 'year_end_amount' => '119.00000'
242
                               },
243
                               {
244
                                 'accno' => '1890',
245
                                 'amount' => undef,
246
                                 'amount_with_cb' => '0.00000',
247
                                 'cat' => 'Q',
248
                                 'cb_amount' => '40.00000',
249
                                 'ob_amount' => '40.00000',
250
                                 'ob_next_year' => '40.00000',
251
                                 'type' => 'asset',
252
                                 'year_end_amount' => '40.00000'
253
                               },
254
                               {
255
                                 'accno' => '9000',
256
                                 'amount' => undef,
257
                                 'amount_with_cb' => '0.00000',
258
                                 'cat' => 'A',
259
                                 'cb_amount' => '0.00000',
260
                                 'ob_amount' => undef,
261
                                 'ob_next_year' => '0.00000',
262
                                 'type' => 'asset',
263
                                 'year_end_amount' => undef
264
                               },
265
                               {
266
                                 'accno' => '1576',
267
                                 'amount' => '-19.00000',
268
                                 'amount_with_cb' => '0.00000',
269
                                 'cat' => 'E',
270
                                 'cb_amount' => '-19.00000',
271
                                 'ob_amount' => undef,
272
                                 'ob_next_year' => undef,
273
                                 'type' => 'pl',
274
                                 'year_end_amount' => '-19.00000'
275
                               },
276
                               {
277
                                 'accno' => '1776',
278
                                 'amount' => '53.20000',
279
                                 'amount_with_cb' => '0.00000',
280
                                 'cat' => 'I',
281
                                 'cb_amount' => '53.20000',
282
                                 'ob_amount' => undef,
283
                                 'ob_next_year' => undef,
284
                                 'type' => 'pl',
285
                                 'year_end_amount' => '53.20000'
286
                               },
287
                               {
288
                                 'accno' => '3400',
289
                                 'amount' => '-100.00000',
290
                                 'amount_with_cb' => '0.00000',
291
                                 'cat' => 'E',
292
                                 'cb_amount' => '-100.00000',
293
                                 'ob_amount' => undef,
294
                                 'ob_next_year' => undef,
295
                                 'type' => 'pl',
296
                                 'year_end_amount' => '-100.00000'
297
                               },
298
                               {
299
                                 'accno' => '8400',
300
                                 'amount' => '280.00000',
301
                                 'amount_with_cb' => '0.00000',
302
                                 'cat' => 'I',
303
                                 'cb_amount' => '280.00000',
304
                                 'ob_amount' => undef,
305
                                 'ob_next_year' => undef,
306
                                 'type' => 'pl',
307
                                 'year_end_amount' => '280.00000'
308
                               }
309
                             ];
310

  
311
# running _year_end_bookings several times shouldn't change the anything, the
312
# second and third run should be no-ops, at least while no further bookings where
313
# made
314

  
315
SL::Controller::YearEndTransactions::_year_end_bookings( start_date => $start_date,
316
                                                         cb_date    => $cb_date,
317
                                                       );
318

  
319
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ cb_transaction => 1 ]), 14, 'acc_trans cb_transactions created ok');
320
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ ob_transaction => 1 ]), 10, 'acc_trans ob_transactions created ok');
321
is(SL::DB::Manager::GLTransaction->get_all_count( where => [ cb_transaction => 1 ]),  5, 'GL cb_transactions created ok');
322
is(SL::DB::Manager::GLTransaction->get_all_count( where => [ ob_transaction => 1 ]),  4, 'GL ob_transactions created ok');
323

  
324

  
325
# all asset accounts should be the same, except 0890, which should be the sum of p/l-accounts
326
# all p/l account should be 0
327

  
328
#  accno |    account_type     |    sum     
329
# -------+---------------------+------------
330
#  0890  | asset_account       |  214.20000
331
#  1200  | asset_account       | -206.60000
332
#  1400  | asset_account       | -166.60000
333
#  1600  | asset_account       |  119.00000
334
#  1890  | asset_account       |   40.00000
335
#  9000  | asset_account       |    0.00000
336
#  1576  | profit_loss_account |    0.00000
337
#  1776  | profit_loss_account |    0.00000
338
#  3400  | profit_loss_account |    0.00000
339
#  8400  | profit_loss_account |    0.00000
340
# (10 rows)
341

  
342
is_deeply( &get_final_balances, 
343
           $final_account_balances,
344
           'balances after second year_end ok (nothing changed)');
345

  
346

  
347
# select c.accno,
348
#        c.description,
349
#        c.category as cat,
350
#        sum(a.amount     ) filter (where ob_transaction is true                              and a.transdate  < '2020-01-01') as ob_amount,
351
#        sum(a.amount     ) filter (where cb_transaction is false and ob_transaction is false and a.transdate  < '2020-01-01') as amount,
352
#        sum(a.amount     ) filter (where cb_transaction is false                             and a.transdate  < '2020-01-01') as year_end_amount,
353
#        sum(a.amount     ) filter (where                                                         a.transdate  < '2020-01-01') as amount_with_cb,
354
#        sum(a.amount * -1) filter (where cb_transaction is true                              and a.transdate  < '2020-01-01') as cb_amount,
355
#        sum(a.amount     ) filter (where ob_transaction is true                              and a.transdate >= '2020-01-01') as ob_next_year,
356
#        case when c.category = ANY( '{I,E}'     ) then 'pl'
357
#             when c.category = ANY( '{A,C,L,Q}' ) then 'asset'
358
#                                                  else null
359
#             end                                                                         as type
360
#   from acc_trans a
361
#        inner join chart c on (c.id = a.chart_id)
362
#  where     a.transdate >= '2019-01-01'
363
#        and a.transdate <= '2020-01-01'
364
#  group by c.id, c.accno, c.category
365
#  order by type, c.accno;
366
#  accno |             description             | cat | ob_amount |   amount   | year_end_amount | amount_with_cb | cb_amount  | ob_next_year | type  
367
# -------+-------------------------------------+-----+-----------+------------+-----------------+----------------+------------+--------------+-------
368
#  0890  | Gewinnvortrag vor Verwendung        | Q   |           |            |                 |        0.00000 |    0.00000 |    214.20000 | asset
369
#  1200  | Bank                                | A   | -40.00000 | -166.60000 |      -206.60000 |        0.00000 | -206.60000 |   -206.60000 | asset
370
#  1400  | Ford. a.Lieferungen und Leistungen  | A   |           | -166.60000 |      -166.60000 |        0.00000 | -166.60000 |   -166.60000 | asset
371
#  1600  | Verbindlichkeiten aus Lief.u.Leist. | L   |           |  119.00000 |       119.00000 |        0.00000 |  119.00000 |    119.00000 | asset
372
#  1890  | Privateinlagen                      | Q   |  40.00000 |            |        40.00000 |        0.00000 |   40.00000 |     40.00000 | asset
373
#  9000  | Saldenvorträge,Sachkonten           | A   |           |            |                 |        0.00000 |    0.00000 |      0.00000 | asset
374
#  1576  | Abziehbare Vorsteuer 19 %           | E   |           |  -19.00000 |       -19.00000 |        0.00000 |  -19.00000 |              | pl
375
#  1776  | Umsatzsteuer 19 %                   | I   |           |   53.20000 |        53.20000 |        0.00000 |   53.20000 |              | pl
376
#  3400  | Wareneingang 16%/19% Vorsteuer      | E   |           | -100.00000 |      -100.00000 |        0.00000 | -100.00000 |              | pl
377
#  8400  | Erlöse 16%/19% USt.                 | I   |           |  280.00000 |       280.00000 |        0.00000 |  280.00000 |              | pl
378
# (10 rows) 
379

  
380
# ob_amount + amount = year_end_amount
381
# amount_with_cb should be 0 after year-end transactions
382
# year_end_amount and cb_amount should be the same (will be true with amount_with_cb = 0)
383
# cb_amount should match ob_next_year for asset accounts, except for profit-carried-forward
384
# ob_next_year should be empty for profit-loss-accounts
385

  
386
# Oops, we forgot some bookings, lets quickly add them and run
387
#_year_end_bookings again.
388

  
389
# Just these new bookings by themselves will lead to a loss, so the loss account
390
# will be booked rather than the profit account.
391
# It would probably be better to check the total profit/loss so far, and
392
# adjust that profit-loss-carry-over # chart, rather than creating a new entry
393
# for the loss.
394

  
395
gl_booking(10, "22.12.$year", 'foo', 'bar', $cash, $bank, 0, 0);
396
gl_booking(5,  "22.12.$year", 'foo', 'bar', $betriebsbedarf, $cash, 0, 0);
397

  
398
SL::Controller::YearEndTransactions::_year_end_bookings( start_date => $start_date,
399
                                                         cb_date    => $cb_date,
400
                                                       );
401

  
402
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ cb_transaction => 1 ]), 23, 'acc_trans cb_transactions created ok');
403
is(SL::DB::Manager::AccTransaction->get_all_count(where => [ ob_transaction => 1 ]), 16, 'acc_trans ob_transactions created ok');
404
is(SL::DB::Manager::GLTransaction->get_all_count( where => [ cb_transaction => 1 ]),  9, 'GL cb_transactions created ok');
405
is(SL::DB::Manager::GLTransaction->get_all_count( where => [ ob_transaction => 1 ]),  7, 'GL ob_transactions created ok');
406

  
407
is_deeply( &get_final_balances, 
408
           [
409
             {
410
               'accno' => '0868',
411
               'amount' => undef,
412
               'amount_with_cb' => '0.00000',
413
               'cat' => 'Q',
414
               'cb_amount' => '0.00000',
415
               'ob_amount' => undef,
416
               'ob_next_year' => '-5.00000',
417
               'type' => 'asset',
418
               'year_end_amount' => undef
419
             },
420
             {
421
               'accno' => '0890',
422
               'amount' => undef,
423
               'amount_with_cb' => '0.00000',
424
               'cat' => 'Q',
425
               'cb_amount' => '0.00000',
426
               'ob_amount' => undef,
427
               'ob_next_year' => '214.20000',
428
               'type' => 'asset',
429
               'year_end_amount' => undef
430
             },
431
             {
432
               'accno' => '1000',
433
               'amount' => '-5.00000',
434
               'amount_with_cb' => '0.00000',
435
               'cat' => 'A',
436
               'cb_amount' => '-5.00000',
437
               'ob_amount' => undef,
438
               'ob_next_year' => '-5.00000',
439
               'type' => 'asset',
440
               'year_end_amount' => '-5.00000'
441
             },
442
             {
443
               'accno' => '1200',
444
               'amount' => '-156.60000',
445
               'amount_with_cb' => '0.00000',
446
               'cat' => 'A',
447
               'cb_amount' => '-196.60000',
448
               'ob_amount' => '-40.00000',
449
               'ob_next_year' => '-196.60000',
450
               'type' => 'asset',
451
               'year_end_amount' => '-196.60000'
452
             },
453
             {
454
               'accno' => '1400',
455
               'amount' => '-166.60000',
456
               'amount_with_cb' => '0.00000',
457
               'cat' => 'A',
458
               'cb_amount' => '-166.60000',
459
               'ob_amount' => undef,
460
               'ob_next_year' => '-166.60000',
461
               'type' => 'asset',
462
               'year_end_amount' => '-166.60000'
463
             },
464
             {
465
               'accno' => '1600',
466
               'amount' => '119.00000',
467
               'amount_with_cb' => '0.00000',
468
               'cat' => 'L',
469
               'cb_amount' => '119.00000',
470
               'ob_amount' => undef,
471
               'ob_next_year' => '119.00000',
472
               'type' => 'asset',
473
               'year_end_amount' => '119.00000'
474
             },
475
             {
476
               'accno' => '1890',
477
               'amount' => undef,
478
               'amount_with_cb' => '0.00000',
479
               'cat' => 'Q',
480
               'cb_amount' => '40.00000',
481
               'ob_amount' => '40.00000',
482
               'ob_next_year' => '40.00000',
483
               'type' => 'asset',
484
               'year_end_amount' => '40.00000'
485
             },
486
             {
487
               'accno' => '9000',
488
               'amount' => undef,
489
               'amount_with_cb' => '0.00000',
490
               'cat' => 'A',
491
               'cb_amount' => '0.00000',
492
               'ob_amount' => undef,
493
               'ob_next_year' => '0.00000',
494
               'type' => 'asset',
495
               'year_end_amount' => undef
496
             },
497
             {
498
               'accno' => '1576',
499
               'amount' => '-19.80000',
500
               'amount_with_cb' => '0.00000',
501
               'cat' => 'E',
502
               'cb_amount' => '-19.80000',
503
               'ob_amount' => undef,
504
               'ob_next_year' => undef,
505
               'type' => 'pl',
506
               'year_end_amount' => '-19.80000'
507
             },
508
             {
509
               'accno' => '1776',
510
               'amount' => '53.20000',
511
               'amount_with_cb' => '0.00000',
512
               'cat' => 'I',
513
               'cb_amount' => '53.20000',
514
               'ob_amount' => undef,
515
               'ob_next_year' => undef,
516
               'type' => 'pl',
517
               'year_end_amount' => '53.20000'
518
             },
519
             {
520
               'accno' => '3400',
521
               'amount' => '-100.00000',
522
               'amount_with_cb' => '0.00000',
523
               'cat' => 'E',
524
               'cb_amount' => '-100.00000',
525
               'ob_amount' => undef,
526
               'ob_next_year' => undef,
527
               'type' => 'pl',
528
               'year_end_amount' => '-100.00000'
529
             },
530
             {
531
               'accno' => '4980',
532
               'amount' => '-4.20000',
533
               'amount_with_cb' => '0.00000',
534
               'cat' => 'E',
535
               'cb_amount' => '-4.20000',
536
               'ob_amount' => undef,
537
               'ob_next_year' => undef,
538
               'type' => 'pl',
539
               'year_end_amount' => '-4.20000'
540
             },
541
             {
542
               'accno' => '8400',
543
               'amount' => '280.00000',
544
               'amount_with_cb' => '0.00000',
545
               'cat' => 'I',
546
               'cb_amount' => '280.00000',
547
               'ob_amount' => undef,
548
               'ob_next_year' => undef,
549
               'type' => 'pl',
550
               'year_end_amount' => '280.00000'
551
             },
552
           ],
553
           'balances after third year_end ok');
554

  
555
clear_up();
556
done_testing;
557

  
558
1;
559

  
560
sub clear_up {
561
  foreach (qw(BankAccount
562
              GLTransaction
563
              AccTransaction
564
              InvoiceItem
565
              Invoice
566
              PurchaseInvoice
567
              Part
568
              Customer
569
             )
570
           ) {
571
    "SL::DB::Manager::${_}"->delete_all(all => 1);
572
  }
573
};
574
 
575
sub get_account_balances {
576
  my $query = <<SQL;
577
  select c.accno,
578
         case when c.category = ANY( '{I,E}'   )   then 'profit_loss_account'
579
              when c.category = ANY( '{A,C,L,Q}' ) then 'asset_account'
580
                                                   else null
581
              end as account_type,
582
         sum(a.amount)
583
    from acc_trans a
584
         left join chart c on (c.id = a.chart_id)
585
group by c.accno, account_type
586
order by account_type, c.accno;
587
SQL
588

  
589
  my $result = selectall_hashref_query($::form, $dbh, $query);
590
  return $result;
591
};
592

  
593
sub get_final_balances {
594
  my $query = <<SQL;
595
 select c.accno,
596
        c.category as cat,
597
        sum(a.amount     ) filter (where ob_transaction is true                              and a.transdate  < ?) as ob_amount,
598
        sum(a.amount     ) filter (where cb_transaction is false and ob_transaction is false and a.transdate  < ?) as amount,
599
        sum(a.amount     ) filter (where cb_transaction is false                             and a.transdate  < ?) as year_end_amount,
600
        sum(a.amount     ) filter (where                                                         a.transdate  < ?) as amount_with_cb,
601
        sum(a.amount * -1) filter (where cb_transaction is true                              and a.transdate  < ?) as cb_amount,
602
        sum(a.amount     ) filter (where ob_transaction is true                              and a.transdate  = ?) as ob_next_year,
603
        case when c.category = ANY( '{I,E}'     ) then 'pl'
604
             when c.category = ANY( '{A,C,L,Q}' ) then 'asset'
605
                                                  else null
606
             end as type
607
   from acc_trans a
608
        inner join chart c on (c.id = a.chart_id)
609
  where     a.transdate >= ?
610
        and a.transdate <= ?
611
  group by c.id, c.accno, c.category
612
  order by type, c.accno
613
SQL
614

  
615
  my $result = selectall_hashref_query($::form, $dbh, $query, $ob_date, $ob_date, $ob_date, $ob_date, $ob_date, $ob_date, $start_date, $ob_date);
616
  return $result;
617
}
618

  
619
sub gl_booking {
620
  # wrapper around SL::Dev::Record::create_gl_transaction for quickly creating transactions
621
  my ($amount, $date, $reference, $description, $gegenkonto, $konto, $ob, $cb) = @_;
622

  
623
  my $transdate = $::locale->parse_date_to_object($date);
624

  
625
  return create_gl_transaction(
626
    ob_transaction => $ob,
627
    cb_transaction => $cb,
628
    transdate      => $transdate,
629
    reference      => $reference,
630
    description    => $description,
631
    bookings       => [
632
                        {
633
                          chart  => $konto,
634
                          credit => $amount,
635
                        },
636
                        {
637
                          chart => $gegenkonto,
638
                          debit => $amount,
639
                        },
640
                      ],
641
  );
642
};

Auch abrufbar als: Unified diff