1 #=====================================================================
 
   4 # Based on SQL-Ledger Version 2.1.9
 
   5 # Web http://www.lx-office.org
 
   7 #=====================================================================
 
   8 # SQL-Ledger Accounting
 
   9 # Copyright (c) 1998-2002
 
  11 #  Author: Dieter Simader
 
  12 #   Email: dsimader@sql-ledger.org
 
  13 #     Web: http://www.sql-ledger.org
 
  16 # This program is free software; you can redistribute it and/or modify
 
  17 # it under the terms of the GNU General Public License as published by
 
  18 # the Free Software Foundation; either version 2 of the License, or
 
  19 # (at your option) any later version.
 
  21 # This program is distributed in the hope that it will be useful,
 
  22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  24 # GNU General Public License for more details.
 
  25 # You should have received a copy of the GNU General Public License
 
  26 # along with this program; if not, write to the Free Software
 
  27 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
  28 #======================================================================
 
  32 #======================================================================
 
  37 use POSIX qw(strftime);
 
  38 use List::Util qw(sum);
 
  44 use SL::ReportGenerator;
 
  46 require "bin/mozilla/common.pl";
 
  47 require "bin/mozilla/drafts.pl";
 
  48 require "bin/mozilla/reportgenerator.pl";
 
  50 # this is for our long dates
 
  51 # $locale->text('January')
 
  52 # $locale->text('February')
 
  53 # $locale->text('March')
 
  54 # $locale->text('April')
 
  55 # $locale->text('May ')
 
  56 # $locale->text('June')
 
  57 # $locale->text('July')
 
  58 # $locale->text('August')
 
  59 # $locale->text('September')
 
  60 # $locale->text('October')
 
  61 # $locale->text('November')
 
  62 # $locale->text('December')
 
  64 # this is for our short month
 
  65 # $locale->text('Jan')
 
  66 # $locale->text('Feb')
 
  67 # $locale->text('Mar')
 
  68 # $locale->text('Apr')
 
  69 # $locale->text('May')
 
  70 # $locale->text('Jun')
 
  71 # $locale->text('Jul')
 
  72 # $locale->text('Aug')
 
  73 # $locale->text('Sep')
 
  74 # $locale->text('Oct')
 
  75 # $locale->text('Nov')
 
  76 # $locale->text('Dec')
 
  79   $main::lxdebug->enter_sub();
 
  81   $main::auth->assert('general_ledger');
 
  83   my $form     = $main::form;
 
  84   my %myconfig = %main::myconfig;
 
  86   return $main::lxdebug->leave_sub() if (load_draft_maybe());
 
  88   $form->{title} = "Add";
 
  90   $form->{callback} = "gl.pl?action=add" unless $form->{callback};
 
  92   # we use this only to set a default date
 
  93   # yep. aber er holt hier auch schon ALL_CHARTS. Aufwand / Nutzen? jb
 
  94   GL->transaction(\%myconfig, \%$form);
 
  96   $form->{rowcount}  = 2;
 
 103   $form->all_departments(\%myconfig);
 
 104   if (@{ $form->{all_departments} || [] }) {
 
 105     $form->{selectdepartment} = "<option>\n";
 
 108       $form->{selectdepartment} .=
 
 109         "<option>$_->{description}--$_->{id}\n"
 
 110     } (@{ $form->{all_departments} || [] });
 
 113   $form->{show_details} = $myconfig{show_form_details} unless defined $form->{show_details};
 
 116   $main::lxdebug->leave_sub();
 
 120 sub prepare_transaction {
 
 121   $main::lxdebug->enter_sub();
 
 123   $main::auth->assert('general_ledger');
 
 125   my $form     = $main::form;
 
 126   my %myconfig = %main::myconfig;
 
 128   GL->transaction(\%myconfig, \%$form);
 
 130   $form->{amount} = $form->format_amount(\%myconfig, $form->{amount}, 2);
 
 133   $form->all_departments(\%myconfig);
 
 134   if (@{ $form->{all_departments} || [] }) {
 
 135     $form->{selectdepartment} = "<option>\n";
 
 138       $form->{selectdepartment} .=
 
 139         "<option>$_->{description}--$_->{id}\n"
 
 140     } (@{ $form->{all_departments} || [] });
 
 146   foreach my $ref (@{ $form->{GL} }) {
 
 148     if ($tax && ($ref->{accno} eq $taxaccno)) {
 
 149       $form->{"tax_$j"}      = abs($ref->{amount});
 
 150       $form->{"taxchart_$j"} = $ref->{id} . "--" . $ref->{taxrate};
 
 151       if ($form->{taxincluded}) {
 
 152         if ($ref->{amount} < 0) {
 
 153           $form->{"debit_$j"} += $form->{"tax_$j"};
 
 155           $form->{"credit_$j"} += $form->{"tax_$j"};
 
 158       $form->{"project_id_$j"} = $ref->{project_id};
 
 161       $form->{"accno_$i"} = "$ref->{accno}--$ref->{tax_id}";
 
 162       for (qw(fx_transaction source memo)) { $form->{"${_}_$i"} = $ref->{$_} }
 
 163       if ($ref->{amount} < 0) {
 
 164         $form->{totaldebit} -= $ref->{amount};
 
 165         $form->{"debit_$i"} = $ref->{amount} * -1;
 
 167         $form->{totalcredit} += $ref->{amount};
 
 168         $form->{"credit_$i"} = $ref->{amount};
 
 170       $form->{"taxchart_$i"} = "0--0.00";
 
 171       $form->{"project_id_$i"} = $ref->{project_id};
 
 174     if ($ref->{taxaccno} && !$tax) {
 
 175       $taxaccno = $ref->{taxaccno};
 
 183   $form->{rowcount} = $i;
 
 185     ($form->datetonum($form->{transdate}, \%myconfig) <=
 
 186      $form->datetonum($form->{closedto}, \%myconfig));
 
 188   $main::lxdebug->leave_sub();
 
 192   $main::lxdebug->enter_sub();
 
 194   $main::auth->assert('general_ledger');
 
 196   my $form     = $main::form;
 
 197   my %myconfig = %main::myconfig;
 
 199   prepare_transaction();
 
 201   $form->{title} = "Edit";
 
 203   $form->{show_details} = $myconfig{show_form_details} unless defined $form->{show_details};
 
 209   $main::lxdebug->leave_sub();
 
 214   $::lxdebug->enter_sub;
 
 215   $::auth->assert('general_ledger');
 
 217   $::form->all_departments(\%::myconfig);
 
 219     projects  => { key => "ALL_PROJECTS", all => 1 },
 
 220     employees => "ALL_EMPLOYEES",
 
 223   my $onload = "focus()"
 
 224              . qq|;setupDateFormat('|. $::myconfig{dateformat} . qq|', '| . $::locale->text("Falsches Datumsformat!") . qq|')|
 
 225              . qq|;setupPoints('|. $::myconfig{numberformat} .   qq|', '| . $::locale->text("wrongformat") . qq|')|;
 
 228   print $::form->parse_html_template('gl/search', {
 
 230     department_label => sub { ("$_[0]{description}--$_[0]{id}")x2 },
 
 231     employee_label => sub { "$_[0]{id}--$_[0]{name}" },
 
 234   $::lxdebug->leave_sub;
 
 237 sub create_subtotal_row {
 
 238   $main::lxdebug->enter_sub();
 
 240   my ($totals, $columns, $column_alignment, $subtotal_columns, $class) = @_;
 
 242   my $form     = $main::form;
 
 243   my %myconfig = %main::myconfig;
 
 245   my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } };
 
 247   map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } @{ $subtotal_columns };
 
 249   map { $totals->{$_} = 0 } @{ $subtotal_columns };
 
 251   $main::lxdebug->leave_sub();
 
 256 sub generate_report {
 
 257   $main::lxdebug->enter_sub();
 
 259   $main::auth->assert('general_ledger');
 
 261   my $form     = $main::form;
 
 262   my %myconfig = %main::myconfig;
 
 263   my $locale   = $main::locale;
 
 265   # generate_report wird beim ersten Aufruf per Weiter-Knopf und POST mit der hidden Variablen sort mit Wert "datesort" (früher "transdate" als Defaultsortiervariable) übertragen
 
 267   # <form method=post action=gl.pl>
 
 268   # <input type=hidden name=sort value=datesort>    # form->{sort} setzen
 
 269   # <input type=hidden name=nextsub value=generate_report>
 
 271   # anhand von neuer Variable datesort wird jetzt $form->{sort} auf transdate oder gldate gesetzt
 
 272   # damit ist die Hidden Variable "sort" wahrscheinlich sogar überflüssig
 
 274   # ändert man die Sortierreihenfolge per Klick auf eine der Überschriften wird die Variable "sort" per GET übergeben, z.B. id,transdate, gldate, ...
 
 275   # gl.pl?action=generate_report&employee=18383--Jan%20B%c3%bcren&datesort=transdate&category=X&l_transdate=Y&l_gldate=Y&l_id=Y&l_reference=Y&l_description=Y&l_source=Y&l_debit=Y&l_credit=Y&sort=gldate&sortdir=0
 
 277   if ( $form->{sort} eq 'datesort' ) {   # sollte bei einem Post (Aufruf aus Suchmaske) immer wahr sein
 
 278       # je nachdem ob in Suchmaske "transdate" oder "gldate" ausgesucht wurde erstes Suchergebnis entsprechend sortieren
 
 279       $form->{sort} = $form->{datesort};
 
 283   report_generator_set_default_sort("$form->{datesort}", 1);
 
 284 #  report_generator_set_default_sort('transdate', 1);
 
 286   GL->all_transactions(\%myconfig, \%$form);
 
 288   my %acctype = ('A' => $locale->text('Asset'),
 
 289                  'C' => $locale->text('Contra'),
 
 290                  'L' => $locale->text('Liability'),
 
 291                  'Q' => $locale->text('Equity'),
 
 292                  'I' => $locale->text('Revenue'),
 
 293                  'E' => $locale->text('Expense'),);
 
 295   $form->{title} = $locale->text('Journal');
 
 296   if ($form->{category} ne 'X') {
 
 297     $form->{title} .= " : " . $locale->text($acctype{ $form->{category} });
 
 300   $form->{landscape} = 1;
 
 302   my $ml = ($form->{ml} =~ /(A|E|Q)/) ? -1 : 1;
 
 305     gldate         transdate        id             reference      description
 
 306     notes          source           debit          debit_accno
 
 307     credit         credit_accno     debit_tax      debit_tax_accno
 
 308     credit_tax     credit_tax_accno projectnumbers balance employee
 
 311   # add employee here, so that variable is still known and passed in url when choosing a different sort order in resulting table
 
 312   my @hidden_variables = qw(accno source reference department description notes project_id datefrom dateto employee datesort category l_subtotal);
 
 313   push @hidden_variables, map { "l_${_}" } @columns;
 
 314   foreach ( @hidden_variables ) {
 
 318   my (@options, @date_options);
 
 319   push @options,      $locale->text('Account')     . " : $form->{accno} $form->{account_description}" if ($form->{accno});
 
 320   push @options,      $locale->text('Source')      . " : $form->{source}"                             if ($form->{source});
 
 321   push @options,      $locale->text('Reference')   . " : $form->{reference}"                          if ($form->{reference});
 
 322   push @options,      $locale->text('Description') . " : $form->{description}"                        if ($form->{description});
 
 323   push @options,      $locale->text('Notes')       . " : $form->{notes}"                              if ($form->{notes});
 
 324   push @options,      $locale->text('Employee')       . " : $form->{employee_name}"                              if ($form->{employee_name});
 
 325   my $datesorttext = $form->{datesort} eq 'transdate' ? $locale->text('Invoice Date') :  $locale->text('Booking Date');
 
 326   push @date_options,      "$datesorttext"                              if ($form->{datesort} and ($form->{datefrom} or $form->{dateto}));
 
 327   push @date_options, $locale->text('From'), $locale->date(\%myconfig, $form->{datefrom}, 1)          if ($form->{datefrom});
 
 328   push @date_options, $locale->text('Bis'),  $locale->date(\%myconfig, $form->{dateto},   1)          if ($form->{dateto});
 
 329   push @options,      join(' ', @date_options)                                                        if (scalar @date_options);
 
 331   if ($form->{department}) {
 
 332     my ($department) = split /--/, $form->{department};
 
 333     push @options, $locale->text('Department') . " : $department";
 
 337   my $callback = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
 
 341   $form->{l_credit_accno}     = 'Y';
 
 342   $form->{l_debit_accno}      = 'Y';
 
 343   $form->{l_credit_tax}       = 'Y';
 
 344   $form->{l_debit_tax}        = 'Y';
 
 345 #  $form->{l_gldate}           = 'Y';  # Spalte mit gldate immer anzeigen
 
 346   $form->{l_credit_tax_accno} = 'Y';
 
 347   $form->{l_datesort} = 'Y';
 
 348   $form->{l_debit_tax_accno}  = 'Y';
 
 349   $form->{l_balance}          = $form->{accno} ? 'Y' : '';
 
 352     'id'               => { 'text' => $locale->text('ID'), },
 
 353     'transdate'        => { 'text' => $locale->text('Invoice Date'), },
 
 354     'gldate'           => { 'text' => $locale->text('Booking Date'), },
 
 355     'reference'        => { 'text' => $locale->text('Reference'), },
 
 356     'source'           => { 'text' => $locale->text('Source'), },
 
 357     'description'      => { 'text' => $locale->text('Description'), },
 
 358     'notes'            => { 'text' => $locale->text('Notes'), },
 
 359     'debit'            => { 'text' => $locale->text('Debit'), },
 
 360     'debit_accno'      => { 'text' => $locale->text('Debit Account'), },
 
 361     'credit'           => { 'text' => $locale->text('Credit'), },
 
 362     'credit_accno'     => { 'text' => $locale->text('Credit Account'), },
 
 363     'debit_tax'        => { 'text' => $locale->text('Debit Tax'), },
 
 364     'debit_tax_accno'  => { 'text' => $locale->text('Debit Tax Account'), },
 
 365     'credit_tax'       => { 'text' => $locale->text('Credit Tax'), },
 
 366     'credit_tax_accno' => { 'text' => $locale->text('Credit Tax Account'), },
 
 367     'balance'          => { 'text' => $locale->text('Balance'), },
 
 368     'projectnumbers'   => { 'text' => $locale->text('Project Numbers'), },
 
 369     'employee'         => { 'text' => $locale->text('Employee'), },
 
 372   foreach my $name (qw(id transdate gldate reference description debit_accno credit_accno debit_tax_accno credit_tax_accno)) {
 
 373     my $sortname                = $name =~ m/accno/ ? 'accno' : $name;
 
 374     my $sortdir                 = $sortname eq $form->{sort} ? 1 - $form->{sortdir} : $form->{sortdir};
 
 375     $column_defs{$name}->{link} = $callback . "&sort=$sortname&sortdir=$sortdir";
 
 378   map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns;
 
 379   map { $column_defs{$_}->{visible} = 0 } qw(debit_accno credit_accno debit_tax_accno credit_tax_accno) if $form->{accno};
 
 381   my %column_alignment;
 
 382   map { $column_alignment{$_}     = 'right'  } qw(balance id debit credit debit_tax credit_tax balance);
 
 383   map { $column_alignment{$_}     = 'center' } qw(transdate gldate reference debit_accno credit_accno debit_tax_accno credit_tax_accno);
 
 384   map { $column_alignment{$_}     = 'left' } qw(description source notes);
 
 385   map { $column_defs{$_}->{align} = $column_alignment{$_} } keys %column_alignment;
 
 387   my $report = SL::ReportGenerator->new(\%myconfig, $form);
 
 389   $report->set_columns(%column_defs);
 
 390   $report->set_column_order(@columns);
 
 392   $report->set_export_options('generate_report', @hidden_variables, qw(sort sortdir));
 
 394   $report->set_sort_indicator($form->{sort} eq 'accno' ? 'debit_accno' : $form->{sort}, $form->{sortdir});
 
 396   $report->set_options('top_info_text'        => join("\n", @options),
 
 397                        'output_format'        => 'HTML',
 
 398                        'title'                => $form->{title},
 
 399                        'attachment_basename'  => $locale->text('general_ledger_list') . strftime('_%Y%m%d', localtime time),
 
 401   $report->set_options_from_form();
 
 402   $locale->set_numberformat_wo_thousands_separator(\%myconfig) if lc($report->{options}->{output_format}) eq 'csv';
 
 404   # add sort to callback
 
 405   $form->{callback} = "$callback&sort=" . E($form->{sort}) . "&sortdir=" . E($form->{sortdir});
 
 408   my @totals_columns = qw(debit credit debit_tax credit_tax);
 
 409   my %subtotals      = map { $_ => 0 } @totals_columns;
 
 410   my %totals         = map { $_ => 0 } @totals_columns;
 
 413   foreach my $ref (@{ $form->{GL} }) {
 
 417     foreach my $key (qw(debit credit debit_tax credit_tax)) {
 
 419       foreach my $idx (sort keys(%{ $ref->{$key} })) {
 
 420         my $value         = $ref->{$key}->{$idx};
 
 421         $subtotals{$key} += $value;
 
 422         $totals{$key}    += $value;
 
 423         if ($key =~ /debit.*/) {
 
 428         $form->{balance}  = $form->{balance} + $value * $ml;
 
 429         push @{ $rows{$key} }, $form->format_amount(\%myconfig, $value, 2);
 
 433     foreach my $key (qw(debit_accno credit_accno debit_tax_accno credit_tax_accno ac_transdate source)) {
 
 434       my $col = $key eq 'ac_transdate' ? 'transdate' : $key;
 
 435       $rows{$col} = [ map { $ref->{$key}->{$_} } sort keys(%{ $ref->{$key} }) ];
 
 439     map { $row->{$_} = { 'data' => '', 'align' => $column_alignment{$_} } } @columns;
 
 442     if ($form->{balance} < 0) {
 
 445     } elsif ($form->{balance} > 0) {
 
 449     my $data = $form->format_amount(\%myconfig, ($form->{balance} * $ml), 2);
 
 452     $row->{balance}->{data}        = $data;
 
 453     $row->{projectnumbers}->{data} = join ", ", sort { lc($a) cmp lc($b) } keys %{ $ref->{projectnumbers} };
 
 455     map { $row->{$_}->{data} = $ref->{$_} } qw(id reference description notes gldate employee);
 
 457     map { $row->{$_}->{data} = \@{ $rows{$_} }; } qw(transdate debit credit debit_accno credit_accno debit_tax_accno credit_tax_accno source);
 
 459     foreach my $col (qw(debit_accno credit_accno debit_tax_accno credit_tax_accno)) {
 
 460       $row->{$col}->{link} = [ map { "${callback}&accno=" . E($_) } @{ $rows{$col} } ];
 
 463     map { $row->{$_}->{data} = \@{ $rows{$_} } if ($ref->{"${_}_accno"} ne "") } qw(debit_tax credit_tax);
 
 465     $row->{reference}->{link} = build_std_url("script=$ref->{module}.pl", 'action=edit', 'id=' . E($ref->{id}), 'callback');
 
 467     my $row_set = [ $row ];
 
 469     if (($form->{l_subtotal} eq 'Y')
 
 470         && (($idx == (scalar @{ $form->{GL} } - 1))
 
 471             || ($ref->{ $form->{sort} } ne $form->{GL}->[$idx + 1]->{ $form->{sort} }))) {
 
 472       push @{ $row_set }, create_subtotal_row(\%subtotals, \@columns, \%column_alignment, [ qw(debit credit) ], 'listsubtotal');
 
 475     $report->add_data($row_set);
 
 480   $report->add_separator();
 
 482   # = 0 for balanced ledger
 
 483   my $balanced_ledger = $totals{debit} + $totals{debit_tax} - $totals{credit} - $totals{credit_tax};
 
 485   my $row = create_subtotal_row(\%totals, \@columns, \%column_alignment, [ qw(debit credit debit_tax credit_tax) ], 'listtotal');
 
 488   if ($form->{balance} < 0) {
 
 491   } elsif ($form->{balance} > 0) {
 
 495   my $data = $form->format_amount(\%myconfig, ($form->{balance} * $ml), 2);
 
 498   $row->{balance}->{data}        = $data;
 
 500   $report->add_data($row);
 
 502   my $raw_bottom_info_text;
 
 504   if (!$form->{accno} && (abs($balanced_ledger) >  0.001)) {
 
 505     $raw_bottom_info_text .=
 
 506         '<p><span class="unbalanced_ledger">'
 
 507       . $locale->text('Unbalanced Ledger')
 
 509       . $form->format_amount(\%myconfig, $balanced_ledger, 3)
 
 513   $raw_bottom_info_text .= $form->parse_html_template('gl/generate_report_bottom');
 
 515   $report->set_options('raw_bottom_info_text' => $raw_bottom_info_text);
 
 517   $report->generate_with_headers();
 
 519   $main::lxdebug->leave_sub();
 
 523   $main::lxdebug->enter_sub();
 
 525   $main::auth->assert('general_ledger');
 
 527   my $form     = $main::form;
 
 528   my %myconfig = %main::myconfig;
 
 530   $form->{oldtransdate} = $form->{transdate};
 
 538   my ($debitcredit, $amount);
 
 541     qw(accno debit credit projectnumber fx_transaction source memo tax taxchart);
 
 543   for my $i (1 .. $form->{rowcount}) {
 
 545     unless (($form->{"debit_$i"} eq "") && ($form->{"credit_$i"} eq "")) {
 
 546       for (qw(debit credit tax)) {
 
 548           $form->parse_amount(\%myconfig, $form->{"${_}_$i"});
 
 552       $debitcredit = ($form->{"debit_$i"} == 0) ? "0" : "1";
 
 559       if (($debitcount >= 2) && ($creditcount == 2)) {
 
 560         $form->{"credit_$i"} = 0;
 
 561         $form->{"tax_$i"}    = 0;
 
 563         $form->{creditlock} = 1;
 
 565       if (($creditcount >= 2) && ($debitcount == 2)) {
 
 566         $form->{"debit_$i"} = 0;
 
 567         $form->{"tax_$i"}   = 0;
 
 569         $form->{debitlock} = 1;
 
 571       if (($creditcount == 1) && ($debitcount == 2)) {
 
 572         $form->{creditlock} = 1;
 
 574       if (($creditcount == 2) && ($debitcount == 1)) {
 
 575         $form->{debitlock} = 1;
 
 577       if ($debitcredit && $credittax) {
 
 578         $form->{"taxchart_$i"} = "0--0.00";
 
 580       if (!$debitcredit && $debittax) {
 
 581         $form->{"taxchart_$i"} = "0--0.00";
 
 584         ($form->{"debit_$i"} == 0)
 
 585         ? $form->{"credit_$i"}
 
 586         : $form->{"debit_$i"};
 
 588       if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
 
 589         $form->{"taxchart_$i"} = "0--0.00";
 
 590         $form->{"tax_$i"}      = 0;
 
 592       my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
 
 599         if ($form->{taxincluded}) {
 
 600           $form->{"tax_$i"} = $amount / ($rate + 1) * $rate;
 
 602           $form->{"tax_$i"} = $amount * $rate;
 
 605         $form->{"tax_$i"} = 0;
 
 608       for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
 
 613   for my $i (1 .. $count) {
 
 615     for (@flds) { $form->{"${_}_$i"} = $a[$j]->{$_} }
 
 618   for my $i ($count + 1 .. $form->{rowcount}) {
 
 619     for (@flds) { delete $form->{"${_}_$i"} }
 
 622   $form->{rowcount} = $count + 1;
 
 625   $main::lxdebug->leave_sub();
 
 631   $main::lxdebug->enter_sub();
 
 633   $main::auth->assert('general_ledger');
 
 635   my $form     = $main::form;
 
 636   my %myconfig = %main::myconfig;
 
 640   #   for $i (1 .. $form->{rowcount}) {
 
 641   #     $form->{totaldebit} += $form->parse_amount(\%myconfig, $form->{"debit_$i"});
 
 642   #     $form->{totalcredit} += $form->parse_amount(\%myconfig, $form->{"credit_$i"});
 
 646   &display_rows($init);
 
 648   $main::lxdebug->leave_sub();
 
 654   $main::lxdebug->enter_sub();
 
 656   $main::auth->assert('general_ledger');
 
 658   my $form     = $main::form;
 
 659   my %myconfig = %main::myconfig;
 
 660   my $cgi      = $::request->{cgi};
 
 662   $form->{debit_1}     = 0 if !$form->{"debit_1"};
 
 663   $form->{totaldebit}  = 0;
 
 664   $form->{totalcredit} = 0;
 
 666   my %project_labels = ();
 
 667   my @project_values = ("");
 
 668   foreach my $item (@{ $form->{"ALL_PROJECTS"} }) {
 
 669     push(@project_values, $item->{"id"});
 
 670     $project_labels{$item->{"id"}} = $item->{"projectnumber"};
 
 673   my %chart_labels = ();
 
 674   my @chart_values = ();
 
 677   foreach my $item (@{ $form->{ALL_CHARTS} }) {
 
 678     if ($item->{charttype} eq 'H'){ #falls überschrift
 
 679       next;                         #überspringen (Bug 1150)
 
 681     my $key = $item->{accno} . "--" . $item->{tax_id};
 
 682     $taxchart_init = $item->{tax_id} unless (@chart_values);
 
 683     push(@chart_values, $key);
 
 684     $chart_labels{$key} = $item->{accno} . "--" . $item->{description};
 
 685     $charts{$item->{accno}} = $item;
 
 688   my %taxchart_labels = ();
 
 689   my @taxchart_values = ();
 
 691   foreach my $item (@{ $form->{ALL_TAXCHARTS} }) {
 
 692     my $key = $item->{id} . "--" . $item->{rate};
 
 693     $taxchart_init = $key if ($taxchart_init == $item->{id});
 
 694     push(@taxchart_values, $key);
 
 695     $taxchart_labels{$key} = $item->{taxdescription} . " " . $item->{rate} * 100 . ' %';
 
 696     $taxcharts{$item->{id}} = $item;
 
 699   my ($source, $memo, $source_hidden, $memo_hidden);
 
 700   for my $i (1 .. $form->{rowcount}) {
 
 701     if ($form->{show_details}) {
 
 703       <td><input name="source_$i" value="$form->{"source_$i"}" size="16"></td>|;
 
 705       <td><input name="memo_$i" value="$form->{"memo_$i"}" size="16"></td>|;
 
 708       <input type="hidden" name="source_$i" value="$form->{"source_$i"}" size="16">|;
 
 710       <input type="hidden" name="memo_$i" value="$form->{"memo_$i"}" size="16">|;
 
 713     my $selected_accno_full;
 
 714     my ($accno_row) = split(/--/, $form->{"accno_$i"});
 
 715     my $item = $charts{$accno_row};
 
 716     $selected_accno_full = "$item->{accno}--$item->{tax_id}";
 
 718     my $selected_taxchart = $form->{"taxchart_$i"};
 
 719     my ($selected_accno, $selected_tax_id) = split(/--/, $selected_accno_full);
 
 720     my ($previous_accno, $previous_tax_id) = split(/--/, $form->{"previous_accno_$i"});
 
 722     if ($previous_accno &&
 
 723         ($previous_accno eq $selected_accno) &&
 
 724         ($previous_tax_id ne $selected_tax_id)) {
 
 725       my $item = $taxcharts{$selected_tax_id};
 
 726       $selected_taxchart = "$item->{id}--$item->{rate}";
 
 729     $selected_accno      = '' if ($init);
 
 730     $selected_taxchart ||= $taxchart_init;
 
 732     my $accno = qq|<td>| .
 
 733       NTI($cgi->popup_menu('-name' => "accno_$i",
 
 735                            '-onChange' => "setTaxkey($i)",
 
 736                            '-style' => 'width:200px',
 
 737                            '-values' => \@chart_values,
 
 738                            '-labels' => \%chart_labels,
 
 739                            '-default' => $selected_accno_full))
 
 740       . $cgi->hidden('-name' => "previous_accno_$i",
 
 741                      '-default' => $selected_accno_full)
 
 743     my $tax_ddbox = qq|<td>| .
 
 744       NTI($cgi->popup_menu('-name' => "taxchart_$i",
 
 745                            '-id' => "taxchart_$i",
 
 746                            '-style' => 'width:200px',
 
 747                            '-values' => \@taxchart_values,
 
 748                            '-labels' => \%taxchart_labels,
 
 749                            '-default' => $selected_taxchart))
 
 752     my ($fx_transaction, $checked);
 
 754       if ($form->{transfer}) {
 
 755         $fx_transaction = qq|
 
 756         <td><input name="fx_transaction_$i" class=checkbox type=checkbox value=1></td>
 
 761       if ($form->{"debit_$i"} != 0) {
 
 762         $form->{totaldebit} += $form->{"debit_$i"};
 
 763         if (!$form->{taxincluded}) {
 
 764           $form->{totaldebit} += $form->{"tax_$i"};
 
 767         $form->{totalcredit} += $form->{"credit_$i"};
 
 768         if (!$form->{taxincluded}) {
 
 769           $form->{totalcredit} += $form->{"tax_$i"};
 
 773       for (qw(debit credit tax)) {
 
 776           ? $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2)
 
 780       if ($i < $form->{rowcount}) {
 
 781         if ($form->{transfer}) {
 
 782           $checked = ($form->{"fx_transaction_$i"}) ? "1" : "";
 
 783           my $x = ($checked) ? "x" : "";
 
 784           $fx_transaction = qq|
 
 785       <td><input type=hidden name="fx_transaction_$i" value="$checked">$x</td>
 
 788         $form->hide_form("accno_$i");
 
 791         if ($form->{transfer}) {
 
 792           $fx_transaction = qq|
 
 793       <td><input name="fx_transaction_$i" class=checkbox type=checkbox value=1></td>
 
 798     my $debitreadonly  = "";
 
 799     my $creditreadonly = "";
 
 800     if ($i == $form->{rowcount}) {
 
 801       if ($form->{debitlock}) {
 
 802         $debitreadonly = "readonly";
 
 803       } elsif ($form->{creditlock}) {
 
 804         $creditreadonly = "readonly";
 
 809       NTI($cgi->popup_menu('-name' => "project_id_$i",
 
 810                            '-values' => \@project_values,
 
 811                            '-labels' => \%project_labels,
 
 812                            '-default' => $form->{"project_id_$i"} ));
 
 813     my $projectnumber_hidden = qq|
 
 814     <input type="hidden" name="project_id_$i" value="$form->{"project_id_$i"}">|;
 
 816     my $copy2credit = $i == 1 ? 'onkeyup="copy_debit_to_credit()"' : '';
 
 818     print qq|<tr valign=top>
 
 820     <td id="chart_balance_$i" align="right"> </td>
 
 822     <td><input name="debit_$i" size="8" value="$form->{"debit_$i"}" accesskey=$i $copy2credit $debitreadonly></td>
 
 823     <td><input name="credit_$i" size=8 value="$form->{"credit_$i"}" $creditreadonly></td>
 
 824     <td><input type="hidden" name="tax_$i" value="$form->{"tax_$i"}">$form->{"tax_$i"}</td>
 
 827     if ($form->{show_details}) {
 
 831     <td>$projectnumber</td>
 
 837     $projectnumber_hidden
 
 845   $form->hide_form(qw(rowcount selectaccno));
 
 847   $main::lxdebug->leave_sub();
 
 853   $main::lxdebug->enter_sub();
 
 855   $main::auth->assert('general_ledger');
 
 857   my $form     = $main::form;
 
 858   my %myconfig = %main::myconfig;
 
 859   my $locale   = $main::locale;
 
 861   my @old_project_ids = ();
 
 862   map({ push(@old_project_ids, $form->{"project_id_$_"})
 
 863           if ($form->{"project_id_$_"}); } (1..$form->{"rowcount"}));
 
 865   $form->get_lists("projects"  => { "key"       => "ALL_PROJECTS",
 
 867                                     "old_id"    => \@old_project_ids },
 
 868                    "charts"    => { "key"       => "ALL_CHARTS",
 
 869                                     "transdate" => $form->{transdate} },
 
 870                    "taxcharts" => "ALL_TAXCHARTS");
 
 872   GL->get_chart_balances('charts' => $form->{ALL_CHARTS});
 
 874   my $title      = $form->{title};
 
 875   $form->{title} = $locale->text("$title General Ledger Transaction");
 
 876   my $readonly   = ($form->{id}) ? "readonly" : "";
 
 878   my $show_details_checked   = $form->{show_details}   ? "checked" : '';
 
 879   my $ob_transaction_checked = $form->{ob_transaction} ? "checked" : '';
 
 880   my $cb_transaction_checked = $form->{cb_transaction} ? "checked" : '';
 
 882   # $locale->text('Add General Ledger Transaction')
 
 883   # $locale->text('Edit General Ledger Transaction')
 
 885   map { $form->{$_} =~ s/\"/"/g }
 
 886     qw(reference description chart taxchart);
 
 888   $form->{javascript} = qq|<script type="text/javascript">
 
 890   function setTaxkey(row) {
 
 891     var accno  = document.getElementById('accno_' + row);
 
 892     var taxkey = accno.options[accno.selectedIndex].value;
 
 893     var reg = /--([0-9]*)/;
 
 894     var found = reg.exec(taxkey);
 
 895     var index = found[1];
 
 896     index = parseInt(index);
 
 897     var tax = 'taxchart_' + row;
 
 898     for (var i = 0; i < document.getElementById(tax).options.length; ++i) {
 
 899       var reg2 = new RegExp("^"+ index, "");
 
 900       if (reg2.exec(document.getElementById(tax).options[i].value)) {
 
 901         document.getElementById(tax).options[i].selected = true;
 
 907   function copy_debit_to_credit() {
 
 908     var txt = document.getElementsByName('debit_1')[0].value;
 
 909     document.getElementsByName('credit_2')[0].value = txt;
 
 913   <script type="text/javascript" src="js/show_form_details.js"></script>
 
 914   <script type="text/javascript" src="js/jquery.js"></script>
 
 917   $form->{selectdepartment} =~ s/ selected//;
 
 918   $form->{selectdepartment} =~
 
 919     s/option>\Q$form->{department}\E/option selected>$form->{department}/;
 
 922   if ((my $rows = $form->numtextrows($form->{description}, 50)) > 1) {
 
 924       qq|<textarea name=description rows=$rows cols=50 wrap=soft $readonly >$form->{description}</textarea>|;
 
 927       qq|<input name=description size=50 value="$form->{description}" $readonly>|;
 
 930   my $taxincluded = ($form->{taxincluded}) ? "checked" : "";
 
 933     $taxincluded = "checked";
 
 939           <th align=right nowrap>| . $locale->text('Department') . qq|</th>
 
 940           <td colspan=3><select name=department>$form->{selectdepartment}</select></td>
 
 941           <input type=hidden name=selectdepartment value="$form->{selectdepartment}">
 
 943 | if $form->{selectdepartment};
 
 945     $form->{fokus} = "gl.reference";
 
 947     $form->{fokus} = qq|gl.accno_$form->{rowcount}|;
 
 950   # use JavaScript Calendar or not
 
 951   $form->{jsscript} = 1;
 
 953   my ($button1, $button2);
 
 954   if ($form->{jsscript}) {
 
 956     # with JavaScript Calendar
 
 958        <td><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" $readonly onBlur=\"check_right_date_format(this)\">
 
 959        <input type=button name=transdate id="trigger1" value=|
 
 960       . $locale->text('button') . qq|></td>
 
 965       Form->write_trigger(\%myconfig, "1", "transdate", "BL", "trigger1");
 
 968     # without JavaScript Calendar
 
 970       qq|<td><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" $readonly onBlur=\"check_right_date_format(this)\"></td>|;
 
 973   $form->{previous_id}     ||= "--";
 
 974   $form->{previous_gldate} ||= "--";
 
 976   $jsscript .= $form->parse_html_template('gl/form_header_chart_balances_js');
 
 981 <body onLoad="focus()">
 
 983 <script type="text/javascript" src="js/follow_up.js"></script>
 
 985 <form method=post name="gl" action=gl.pl>
 
 988   $form->hide_form(qw(id closedto locked storno storno_id previous_id previous_gldate));
 
 991 <input type=hidden name=title value="$title">
 
 993 <input type="hidden" name="follow_up_trans_id_1" value="| . H($form->{id}) . qq|">
 
 994 <input type="hidden" name="follow_up_trans_type_1" value="gl_transaction">
 
 995 <input type="hidden" name="follow_up_trans_info_1" value="| . H($form->{id}) . qq|">
 
 996 <input type="hidden" name="follow_up_rowcount" value="1">
 
1000     <th class=listtop>$form->{title}</th>
 
1003   ($form->{saved_message} ? qq|
 
1005     <td>$form->{saved_message}</th>
 
1009   <tr height="5"></tr>
 
1014           <td colspan="6" align="left">|
 
1015     . $locale->text("Previous transnumber text")
 
1016     . " $form->{previous_id} "
 
1017     . $locale->text("Previous transdate text")
 
1018     . " $form->{previous_gldate}"
 
1022           <th align=right>| . $locale->text('Reference') . qq|</th>
 
1023           <td><input name=reference size=20 value="$form->{reference}" $readonly></td>
 
1027                 <th align=right nowrap>| . $locale->text('Date') . qq|</th>
 
1036           <th align=right>| . $locale->text('Belegnummer') . qq|</th>
 
1037           <td><input name=id size=20 value="$form->{id}" $readonly></td>
 
1041                 <th align=right width=50%>| . $locale->text('Buchungsdatum') . qq|</th>
 
1042                 <td align=left><input name=gldate size=11 title="$myconfig{dateformat}" value=$form->{gldate} $readonly onBlur=\"check_right_date_format(this)\"></td>
 
1053           <th align=right width=1%>| . $locale->text('Description') . qq|</th>
 
1054           <td width=1%>$description</td>
 
1058                 <th align=left>| . $locale->text('MwSt. inkl.') . qq|</th>
 
1059                 <td><input type=checkbox name=taxincluded value=1 $taxincluded></td>
 
1066                 <th align=right width=50%>| . $locale->text('Mitarbeiter') . qq|</th>
 
1067                 <td align=left><input name=employee size=20  value="| . H($form->{employee}) . qq|" readonly></td>
 
1075           <th align=left width=1%>| . $locale->text('Description') . qq|</th>
 
1076           <td width=1%>$description</td>
 
1080                 <th align=left>| . $locale->text('MwSt. inkl.') . qq|</th>
 
1081                 <td><input type=checkbox name=taxincluded value=1 $taxincluded></td>
 
1090       <tr><td colspan=4><table><tr>
 
1092         | . $locale->text('OB Transaction') . qq|<input type="checkbox" name="ob_transaction" value="1" $ob_transaction_checked>
 
1095         | . $locale->text('CB Transaction') . qq|<input type="checkbox" name="cb_transaction" value="1" $cb_transaction_checked>
 
1097       </tr></table></td></tr>
 
1099        <td width="1%" align="right" nowrap>| . $locale->text('Show details') . qq|</td>
 
1100        <td width="1%"><input type="checkbox" onclick="show_form_details();" name="show_details" value="1" $show_details_checked></td>
 
1107            <tr class=listheading>
 
1108           <th class=listheading style="width:15%">|
 
1109     . $locale->text('Account') . qq|</th>
 
1110           <th class=listheading style="width:10%">| . $locale->text('Chart balance') . qq|</th>
 
1111           <th class=listheading style="width:10%">|
 
1112     . $locale->text('Debit') . qq|</th>
 
1113           <th class=listheading style="width:10%">|
 
1114     . $locale->text('Credit') . qq|</th>
 
1115           <th class=listheading style="width:10%">|
 
1116     . $locale->text('Tax') . qq|</th>
 
1117           <th class=listheading style="width:5%">|
 
1118     . $locale->text('Taxkey') . qq|</th>|;
 
1120   if ($form->{show_details}) {
 
1122           <th class=listheading style="width:20%">| . $locale->text('Source') . qq|</th>
 
1123           <th class=listheading style="width:20%">| . $locale->text('Memo') . qq|</th>
 
1124           <th class=listheading style="width:20%">| . $locale->text('Project Number') . qq|</th>
 
1133   $main::lxdebug->leave_sub();
 
1138   $main::lxdebug->enter_sub();
 
1140   $main::auth->assert('general_ledger');
 
1142   my $form     = $main::form;
 
1143   my %myconfig = %main::myconfig;
 
1144   my $locale   = $main::locale;
 
1145   my $cgi      = $::request->{cgi};
 
1147   my $follow_ups_block;
 
1149     my $follow_ups = FU->follow_ups('trans_id' => $form->{id});
 
1151     if (@{ $follow_ups} ) {
 
1152       my $num_due       = sum map { $_->{due} * 1 } @{ $follow_ups };
 
1153       $follow_ups_block = qq|<p>| . $locale->text("There are #1 unfinished follow-ups of which #2 are due.", scalar @{ $follow_ups }, $num_due) . qq|</p>|;
 
1157   my ($dec) = ($form->{totaldebit} =~ /\.(\d+)/);
 
1159   my $decimalplaces = ($dec > 2) ? $dec : 2;
 
1160   my $radieren = ($form->current_date(\%myconfig) eq $form->{gldate}) ? 1 : 0;
 
1163     $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2, " ")
 
1164   } qw(totaldebit totalcredit);
 
1167     <tr class=listtotal>
 
1168     <th colspan="3" align=right class=listtotal> $form->{totaldebit}</th>
 
1169     <th align=right class=listtotal> $form->{totalcredit}</th>
 
1177 <input name=callback type=hidden value="$form->{callback}">
 
1184   my $transdate = $form->datetonum($form->{transdate}, \%myconfig);
 
1185   my $closedto  = $form->datetonum($form->{closedto},  \%myconfig);
 
1189     if (!$form->{storno}) {
 
1190       print qq|<input class=submit type=submit name=action value="| . $locale->text('Storno') . qq|">|;
 
1193     # Löschen und Ändern von Buchungen nicht mehr möglich (GoB) nur am selben Tag möglich
 
1194     if (!$form->{locked} && $radieren) {
 
1196         <input class=submit type=submit name=action value="| . $locale->text('Post') . qq|" accesskey="b">
 
1197         <input class=submit type=submit name=action value="| . $locale->text('Delete') . qq|">|;
 
1201         <input class=submit type=submit name=action id=update_button value="| . $locale->text('Update') . qq|">
 
1202         <input type="button" class="submit" onclick="follow_up_window()" value="|
 
1203       . $locale->text('Follow-Up')
 
1207     if ($form->{draft_id}) {
 
1208       my $remove_draft_checked = $form->{remove_draft} ? 'checked' : '';
 
1210         . qq|  <input name="remove_draft" id="remove_draft" type="checkbox" class="checkbox" ${remove_draft_checked}>|
 
1211         . qq|  <label for="remove_draft">| . $locale->text('Remove Draft') . qq|</label>\n|
 
1216         <input class=submit type=submit name=action id=update_button value="| . $locale->text('Update') . qq|">
 
1217         <input class=submit type=submit name=action value="| . $locale->text('Post') . qq|"> |
 
1218         . NTI($cgi->submit('-name' => 'action', '-value' => $locale->text('Save draft'), '-class' => 'submit'))
 
1219         . $cgi->hidden('-name' => 'draft_id',          '-default' => [$form->{draft_id}])
 
1220         . $cgi->hidden('-name' => 'draft_description', '-default' => [$form->{draft_description}]);
 
1229   $main::lxdebug->leave_sub();
 
1234   $main::lxdebug->enter_sub();
 
1236   my $form     = $main::form;
 
1237   my $locale   = $main::locale;
 
1244 <form method=post action=gl.pl>
 
1247   map { $form->{$_} =~ s/\"/"/g } qw(reference description);
 
1249   delete $form->{header};
 
1251   foreach my $key (keys %$form) {
 
1252     next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key}));
 
1253     print qq|<input type="hidden" name="$key" value="$form->{$key}">\n|;
 
1257 <h2 class=confirm>| . $locale->text('Confirm!') . qq|</h2>
 
1260     . $locale->text('Are you sure you want to delete Transaction')
 
1261     . qq| $form->{reference}</h4>
 
1263 <input name=action class=submit type=submit value="|
 
1264     . $locale->text('Yes') . qq|">
 
1267   $main::lxdebug->leave_sub();
 
1272   $main::lxdebug->enter_sub();
 
1274   my $form     = $main::form;
 
1275   my %myconfig = %main::myconfig;
 
1276   my $locale   = $main::locale;
 
1278   if (GL->delete_transaction(\%myconfig, \%$form)){
 
1279     # saving the history
 
1280       if(!exists $form->{addition} && $form->{id} ne "") {
 
1281         $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
 
1282         $form->{addition} = "DELETED";
 
1283         $form->save_history;
 
1285     # /saving the history
 
1286     $form->redirect($locale->text('Transaction deleted!'))
 
1288   $form->error($locale->text('Cannot delete transaction!'));
 
1289   $main::lxdebug->leave_sub();
 
1293 sub post_transaction {
 
1294   $main::lxdebug->enter_sub();
 
1296   my $form     = $main::form;
 
1297   my %myconfig = %main::myconfig;
 
1298   my $locale   = $main::locale;
 
1300   # check if there is something in reference and date
 
1301   $form->isblank("reference",   $locale->text('Reference missing!'));
 
1302   $form->isblank("transdate",   $locale->text('Transaction Date missing!'));
 
1303   $form->isblank("description", $locale->text('Description missing!'));
 
1305   my $transdate = $form->datetonum($form->{transdate}, \%myconfig);
 
1306   my $closedto  = $form->datetonum($form->{closedto},  \%myconfig);
 
1313   my $creditcount = 0;
 
1315   my %split_safety = ();
 
1317   my @flds = qw(accno debit credit projectnumber fx_transaction source memo tax taxchart);
 
1319   for my $i (1 .. $form->{rowcount}) {
 
1320     next if $form->{"debit_$i"} eq "" && $form->{"credit_$i"} eq "";
 
1322     for (qw(debit credit tax)) {
 
1323       $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"});
 
1327     $debitcredit = ($form->{"debit_$i"} == 0) ? "0" : "1";
 
1329     $split_safety{   $form->{"debit_$i"}  <=> 0 }++;
 
1330     $split_safety{ - $form->{"credit_$i"} <=> 0 }++;
 
1338     if (($debitcount >= 2) && ($creditcount == 2)) {
 
1339       $form->{"credit_$i"} = 0;
 
1340       $form->{"tax_$i"}    = 0;
 
1342       $form->{creditlock} = 1;
 
1344     if (($creditcount >= 2) && ($debitcount == 2)) {
 
1345       $form->{"debit_$i"} = 0;
 
1346       $form->{"tax_$i"}   = 0;
 
1348       $form->{debitlock} = 1;
 
1350     if (($creditcount == 1) && ($debitcount == 2)) {
 
1351       $form->{creditlock} = 1;
 
1353     if (($creditcount == 2) && ($debitcount == 1)) {
 
1354       $form->{debitlock} = 1;
 
1356     if ($debitcredit && $credittax) {
 
1357       $form->{"taxchart_$i"} = "0--0.00";
 
1359     if (!$debitcredit && $debittax) {
 
1360       $form->{"taxchart_$i"} = "0--0.00";
 
1362     my $amount = ($form->{"debit_$i"} == 0)
 
1363             ? $form->{"credit_$i"}
 
1364             : $form->{"debit_$i"};
 
1366     if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
 
1367       $form->{"taxchart_$i"} = "0--0.00";
 
1368       $form->{"tax_$i"}      = 0;
 
1370     my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
 
1377       if ($form->{taxincluded}) {
 
1378         $form->{"tax_$i"} = $amount / ($rate + 1) * $rate;
 
1380           $form->{"debit_$i"} = $form->{"debit_$i"} - $form->{"tax_$i"};
 
1382           $form->{"credit_$i"} = $form->{"credit_$i"} - $form->{"tax_$i"};
 
1385         $form->{"tax_$i"} = $amount * $rate;
 
1388       $form->{"tax_$i"} = 0;
 
1391     for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
 
1395   if ($split_safety{-1} > 1 && $split_safety{1} > 1) {
 
1396     $::form->error($::locale->text("Split entry detected. The values you have entered will result in an entry with more than one position on both debit and credit. Due to known problems involving accounting software Lx-Office does not allow these."));
 
1399   for my $i (1 .. $count) {
 
1401     for (@flds) { $form->{"${_}_$i"} = $a[$j]->{$_} }
 
1404   for my $i ($count + 1 .. $form->{rowcount}) {
 
1405     for (@flds) { delete $form->{"${_}_$i"} }
 
1408   my ($debit, $credit, $taxtotal);
 
1409   for my $i (1 .. $form->{rowcount}) {
 
1410     my $dr  = $form->{"debit_$i"};
 
1411     my $cr  = $form->{"credit_$i"};
 
1412     my $tax = $form->{"tax_$i"};
 
1414       $form->error($locale->text('Cannot post transaction with a debit and credit entry for the same account!'));
 
1416     $debit    += $dr + $tax if $dr;
 
1417     $credit   += $cr + $tax if $cr;
 
1418     $taxtotal += $tax if $form->{taxincluded}
 
1421   $form->{taxincluded} = 0 if !$taxtotal;
 
1423   # this is just for the wise guys
 
1424   $form->error($locale->text('Cannot post transaction for a closed period!'))
 
1425     if ($form->date_closed($form->{"transdate"}, \%myconfig));
 
1426   if ($form->round_amount($debit, 2) != $form->round_amount($credit, 2)) {
 
1427     $form->error($locale->text('Out of balance transaction!'));
 
1430   if ($form->round_amount($debit, 2) + $form->round_amount($credit, 2) == 0) {
 
1431     $form->error($locale->text('Empty transaction!'));
 
1434   if ((my $errno = GL->post_transaction(\%myconfig, \%$form)) <= -1) {
 
1437     $err[1] = $locale->text('Cannot have a value in both Debit and Credit!');
 
1438     $err[2] = $locale->text('Debit and credit out of balance!');
 
1439     $err[3] = $locale->text('Cannot post a transaction without a value!');
 
1441     $form->error($err[$errno]);
 
1443   undef($form->{callback});
 
1444   # saving the history
 
1445   if(!exists $form->{addition} && $form->{id} ne "") {
 
1446     $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
 
1447     $form->{addition} = "SAVED";
 
1448     $form->{what_done} = $locale->text("Buchungsnummer") . " = " . $form->{id};
 
1449     $form->save_history;
 
1451   # /saving the history
 
1453   $main::lxdebug->leave_sub();
 
1457   $main::lxdebug->enter_sub();
 
1459   $main::auth->assert('general_ledger');
 
1461   my $form     = $main::form;
 
1462   my $locale   = $main::locale;
 
1464   if ($::myconfig{mandatory_departments} && !$form->{department}) {
 
1465     $form->{saved_message} = $::locale->text('You have to specify a department.');
 
1470   $form->{title}  = $locale->text("$form->{title} General Ledger Transaction");
 
1471   $form->{storno} = 0;
 
1475   remove_draft() if $form->{remove_draft};
 
1477   $form->{callback} = build_std_url("action=add&DONT_LOAD_DRAFT=1", "show_details");
 
1478   $form->redirect($form->{callback});
 
1480   $main::lxdebug->leave_sub();
 
1484   $main::lxdebug->enter_sub();
 
1486   $main::auth->assert('general_ledger');
 
1488   my $form     = $main::form;
 
1492   $main::lxdebug->leave_sub();
 
1497   $main::lxdebug->enter_sub();
 
1499   $main::auth->assert('general_ledger');
 
1501   my $form     = $main::form;
 
1502   my %myconfig = %main::myconfig;
 
1503   my $locale   = $main::locale;
 
1505   # don't cancel cancelled transactions
 
1506   if (IS->has_storno(\%myconfig, $form, 'gl')) {
 
1507     $form->{title} = $locale->text("Cancel Accounts Receivables Transaction");
 
1508     $form->error($locale->text("Transaction has already been cancelled!"));
 
1511   GL->storno($form, \%myconfig, $form->{id});
 
1513   # saving the history
 
1514   if(!exists $form->{addition} && $form->{id} ne "") {
 
1515     $form->{snumbers} = "ordnumber_$form->{ordnumber}";
 
1516     $form->{addition} = "STORNO";
 
1517     $form->save_history;
 
1519   # /saving the history
 
1521   $form->redirect(sprintf $locale->text("Transaction %d cancelled."), $form->{storno_id});
 
1523   $main::lxdebug->leave_sub();
 
1527   call_sub($main::form->{nextsub});