sub language {
   $main::lxdebug->enter_sub();
 
-  my ($self, $myconfig, $form) = @_;
+  my ($self, $myconfig, $form, $return_list) = @_;
 
   # connect to database
   my $dbh = $form->dbconnect($myconfig);
 
-  my $query = qq|SELECT id, description, template_code, article_code
-                 FROM language
-                ORDER BY 2|;
+  my $query =
+    "SELECT id, description, template_code, article_code, " .
+    "  output_numberformat, output_dateformat, output_longdates " .
+    "FROM language ORDER BY description";
 
   $sth = $dbh->prepare($query);
   $sth->execute || $form->dberror($query);
 
+  my $ary = [];
+
   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
-    push @{ $form->{ALL} }, $ref;
+    push(@{ $ary }, $ref);
   }
 
   $sth->finish;
   $dbh->disconnect;
 
   $main::lxdebug->leave_sub();
+
+  if ($return_list) {
+    return @{$ary};
+  } else {
+    $form->{ALL} = $ary;
+  }
 }
 
 sub get_language {
   my $dbh = $form->dbconnect($myconfig);
 
   my $query =
-    qq|SELECT l.description, l.template_code, l.article_code
-                 FROM language l
-                WHERE l.id = $form->{id}|;
+    "SELECT description, template_code, article_code, " .
+    "  output_numberformat, output_dateformat, output_longdates " .
+    "FROM language WHERE id = ?";
   my $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute($form->{"id"}) || $form->dberror($query . " ($form->{id})");
 
   my $ref = $sth->fetchrow_hashref(NAME_lc);
 
   $main::lxdebug->leave_sub();
 }
 
+sub get_language_details {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form, $id) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query =
+    "SELECT template_code, " .
+    "  output_numberformat, output_dateformat, output_longdates " .
+    "FROM language WHERE id = ?";
+  my @res = $dbh->selectrow_array($query, undef, $id);
+  $dbh->disconnect;
+
+  $main::lxdebug->leave_sub();
+
+  return @res;
+}
+
 sub save_language {
   $main::lxdebug->enter_sub();
 
 
   # connect to database
   my $dbh = $form->dbconnect($myconfig);
+  my (@values, $query);
 
-  $form->{description} =~ s/\'/\'\'/g;
-  $form->{article_code} =~ s/\'/\'\'/g;
-  $form->{template_code} =~ s/\'/\'\'/g;
-
+  map({ push(@values, $form->{$_}); }
+      qw(description template_code article_code
+         output_numberformat output_dateformat output_longdates));
 
   # id is the old record
   if ($form->{id}) {
-    $query = qq|UPDATE language SET
-               description = '$form->{description}',
-               template_code = '$form->{template_code}',
-               article_code = '$form->{article_code}'
-               WHERE id = $form->{id}|;
+    $query =
+      "UPDATE language SET " .
+      "  description = ?, template_code = ?, article_code = ?, " .
+      "  output_numberformat = ?, output_dateformat = ?, " .
+      "  output_longdates = ? " .
+      "WHERE id = ?";
+    push(@values, $form->{id});
   } else {
-    $query = qq|INSERT INTO language
-                (description, template_code, article_code)
-                VALUES ('$form->{description}', '$form->{template_code}', '$form->{article_code}')|;
+    $query =
+      "INSERT INTO language (" .
+      "  description, template_code, article_code, " .
+      "  output_numberformat, output_dateformat, output_longdates" .
+      ") VALUES (?, ?, ?, ?, ?, ?)";
   }
-  $dbh->do($query) || $form->dberror($query);
+  $dbh->do($query, undef, @values) ||
+    $form->dberror($query . " (" . join(", ", @values) . ")");
 
   $dbh->disconnect;
 
   my ($self, $myconfig, $form) = @_;
 
   # connect to database
-  my $dbh = $form->dbconnect($myconfig);
+  my $dbh = $form->dbconnect_noauto($myconfig);
 
-  $query = qq|DELETE FROM language
-             WHERE id = $form->{id}|;
-  $dbh->do($query) || $form->dberror($query);
+  my $query = "DELETE FROM units_language WHERE language_id = ?";
+  $dbh->do($query, undef, $form->{"id"}) ||
+    $form->dberror($query . " ($form->{id})");
+
+  $query = "DELETE FROM language WHERE id = ?";
+  $dbh->do($query, undef, $form->{"id"}) ||
+    $form->dberror($query . " ($form->{id})");
 
+  $dbh->commit();
   $dbh->disconnect;
 
   $main::lxdebug->leave_sub();
 
   }
 
-  $query = "SELECT inventory_accno_id FROM defaults";
-  ($form->{"std_inventory_accno_id"}) = $dbh->selectrow_array($query);
+  $query = "SELECT inventory_accno_id, income_accno_id, expense_accno_id ".
+    "FROM defaults";
+  ($form->{"std_inventory_accno_id"}, $form->{"std_income_accno_id"},
+   $form->{"std_expense_accno_id"}) = $dbh->selectrow_array($query);
 
   my $module = "IC";
   $query = qq|SELECT c.accno, c.description, c.link, c.id,
                  servicenumber = '$form->{servicenumber}',
                  yearend = '$form->{yearend}',
                 curr = '$form->{curr}',
-                weightunit = '$form->{weightunit}',
                 businessnumber = '$form->{businessnumber}'
                |;
   $dbh->do($query) || $form->dberror($query);
   }
   $sth->finish();
 
-  foreach my $unit (keys(%{$units})) {
-    ($units->{$unit}->{"${prefix}base_unit"}, $units->{$unit}->{"${prefix}factor"}) = AM->get_base_unit($units, $unit);
+  my $query_lang = "SELECT id, template_code FROM language ORDER BY description";
+  $sth = $dbh->prepare($query_lang);
+  $sth->execute() || $form->dberror($query_lang);
+  my @languages;
+  while ($ref = $sth->fetchrow_hashref()) {
+    push(@languages, $ref);
+  }
+  $sth->finish();
+
+  $query_lang = "SELECT ul.localized, ul.localized_plural, l.id, l.template_code " .
+    "FROM units_language ul " .
+    "LEFT JOIN language l ON ul.language_id = l.id " .
+    "WHERE ul.unit = ?";
+  $sth = $dbh->prepare($query_lang);
+
+  foreach my $unit (values(%{$units})) {
+    ($unit->{"${prefix}base_unit"}, $unit->{"${prefix}factor"}) = AM->get_base_unit($units, $unit->{"name"});
+
+    $unit->{"LANGUAGES"} = {};
+    foreach my $lang (@languages) {
+      $unit->{"LANGUAGES"}->{$lang->{"template_code"}} = { "template_code" => $lang->{"template_code"} };
+    }
+
+    $sth->execute($unit->{"name"}) || $form->dberror($query_lang . " (" . $unit->{"name"} . ")");
+    while ($ref = $sth->fetchrow_hashref()) {
+      map({ $unit->{"LANGUAGES"}->{$ref->{"template_code"}}->{$_} = $ref->{$_} } keys(%{$ref}));
+    }
   }
+  $sth->finish();
 
   $dbh->disconnect();
 
   return $units;
 }
 
+sub translate_units {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $form, $template_code, $unit, $amount) = @_;
+
+  my $units = $self->retrieve_units(\%main::myconfig, $form);
+
+  my $h = $units->{$unit}->{"LANGUAGES"}->{$template_code};
+  my $new_unit = $unit;
+  if ($h) {
+    if (($amount != 1) && $h->{"localized_plural"}) {
+      $new_unit = $h->{"localized_plural"};
+    } elsif ($h->{"localized"}) {
+      $new_unit = $h->{"localized"};
+    }
+  }
+
+  $main::lxdebug->leave_sub();
+
+  return $new_unit;
+}
+
 sub units_in_use {
   $main::lxdebug->enter_sub();
 
 sub add_unit {
   $main::lxdebug->enter_sub();
 
-  my ($self, $myconfig, $form, $name, $base_unit, $factor, $type) = @_;
+  my ($self, $myconfig, $form, $name, $base_unit, $factor, $type, $languages) = @_;
 
-  my $dbh = $form->dbconnect($myconfig);
+  my $dbh = $form->dbconnect_noauto($myconfig);
 
   my $query = "INSERT INTO units (name, base_unit, factor, type) VALUES (?, ?, ?, ?)";
   $dbh->do($query, undef, $name, $base_unit, $factor, $type) || $form->dberror($query . " ($name, $base_unit, $factor, $type)");
+
+  if ($languages) {
+    $query = "INSERT INTO units_language (unit, language_id, localized, localized_plural) VALUES (?, ?, ?, ?)";
+    my $sth = $dbh->prepare($query);
+    foreach my $lang (@{$languages}) {
+      my @values = ($name, $lang->{"id"}, $lang->{"localized"}, $lang->{"localized_plural"});
+      $sth->execute(@values) || $form->dberror($query . " (" . join(", ", @values) . ")");
+    }
+    $sth->finish();
+  }
+
+  $dbh->commit();
   $dbh->disconnect();
 
   $main::lxdebug->leave_sub();
 
   my ($base_unit, $unit, $sth, $query);
 
+  $query = "DELETE FROM units_language";
+  $dbh->do($query) || $form->dberror($query);
+
   if ($delete_units && (0 != scalar(@{$delete_units}))) {
-    $query = "DELETE FROM units WHERE name = ?";
-    $sth = $dbh->prepare($query);
-    map({ $sth->execute($_) || $form->dberror($query . " ($_)"); } @{$delete_units});
-    $sth->finish();
+    $query = "DELETE FROM units WHERE name IN (";
+    map({ $query .= "?," } @{$delete_units});
+    substr($query, -1, 1) = ")";
+    $dbh->do($query, undef, @{$delete_units}) ||
+      $form->dberror($query . " (" . join(", ", @{$delete_units}) . ")");
   }
 
   $query = "UPDATE units SET name = ?, base_unit = ?, factor = ? WHERE name = ?";
   $sth = $dbh->prepare($query);
 
+  my $query_lang = "INSERT INTO units_language (unit, language_id, localized, localized_plural) VALUES (?, ?, ?, ?)";
+  my $sth_lang = $dbh->prepare($query_lang);
+
   foreach $unit (values(%{$units})) {
     $unit->{"depth"} = 0;
     my $base_unit = $unit;
   }
 
   foreach $unit (sort({ $a->{"depth"} <=> $b->{"depth"} } values(%{$units}))) {
+    if ($unit->{"LANGUAGES"}) {
+      foreach my $lang (@{$unit->{"LANGUAGES"}}) {
+        next unless ($lang->{"id"} && $lang->{"localized"});
+        my @values = ($unit->{"name"}, $lang->{"id"}, $lang->{"localized"}, $lang->{"localized_plural"});
+        $sth_lang->execute(@values) || $form->dberror($query_lang . " (" . join(", ", @values) . ")");
+      }
+    }
+
     next if ($unit->{"unchanged_unit"});
 
     my @values = ($unit->{"name"}, $unit->{"base_unit"}, $unit->{"factor"}, $unit->{"old_name"});
   }
 
   $sth->finish();
+  $sth_lang->finish();
   $dbh->commit();
   $dbh->disconnect();
 
 
   $main::lxdebug->leave_sub();
 }
 
+sub get_transdate {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query =
+    "SELECT COALESCE(" .
+    "  (SELECT transdate FROM gl WHERE id = " .
+    "    (SELECT MAX(id) FROM gl) LIMIT 1), " .
+    "  current_date)";
+  ($form->{transdate}) = $dbh->selectrow_array($query);
+
+  $dbh->disconnect;
+
+  $main::lxdebug->leave_sub();
+}
+
 1;
 
 
   my $query = qq|SELECT a.id, a.invnumber, a.ordnumber, a.transdate,
                  a.duedate, a.netamount, a.amount, a.paid, c.name,
                 a.invoice, a.datepaid, a.terms, a.notes, a.shipvia,
-                a.shippingpoint,
+                a.shippingpoint, a.storno,
                 e.name AS employee
                 FROM ar a
              JOIN customer c ON (a.customer_id = c.id)
   $main::lxdebug->leave_sub();
 }
 
+sub get_transdate {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query =
+    "SELECT COALESCE(" .
+    "  (SELECT transdate FROM gl WHERE id = " .
+    "    (SELECT MAX(id) FROM gl) LIMIT 1), " .
+    "  current_date)";
+  ($form->{transdate}) = $dbh->selectrow_array($query);
+
+  $dbh->disconnect;
+
+  $main::lxdebug->leave_sub();
+}
+
 1;
 
 
 
 package CT;
 use Data::Dumper;
-
+use SL::DBUtils;
 
 sub get_tuple {
   $main::lxdebug->enter_sub();
   $form->{obsolete}    *= 1;
   $form->{business}    *= 1;
   $form->{salesman_id} *= 1;
-  $form->{language_id} *= 1;
   $form->{payment_id} *= 1;
   $form->{taxzone_id} *= 1;
   $form->{creditlimit} = $form->parse_amount($myconfig, $form->{creditlimit});
               ustid = '$form->{ustid}',
               username = '$form->{username}',
               salesman_id = '$form->{salesman_id}',
-              language_id = '$form->{language_id}',
+              language_id = | . conv_i($form->{language_id}, "NULL") . qq|,
               payment_id = '$form->{payment_id}',
               taxzone_id = '$form->{taxzone_id}',
               user_password = | . $dbh->quote($form->{user_password}) . qq|,
       $dbh->do($query) || $form->dberror($query);
     }
   }
-  print(STDERR "SHIPTO_ID $form->{shipto_id}\n");
   # add shipto
   $form->add_shipto($dbh, $form->{id}, "CT");
 
   $form->{obsolete}    *= 1;
   $form->{business}    *= 1;
   $form->{payment_id}    *= 1;
-  $form->{language_id}    *= 1;
   $form->{taxzone_id}    *= 1;
   $form->{creditlimit} = $form->parse_amount($myconfig, $form->{creditlimit});
 
               ustid = '$form->{ustid}',
               payment_id = '$form->{payment_id}',
               taxzone_id = '$form->{taxzone_id}',
-              language_id = '$form->{language_id}',
+              language_id = | . conv_i($form->{language_id}, "NULL") . qq|,
               username = '$form->{username}',
               user_password = '$form->{user_password}',
               v_customer_id = '$form->{v_customer_id}'
 
 
 package Common;
 
+use Time::HiRes qw(gettimeofday);
+
+sub unique_id {
+  my ($a, $b) = gettimeofday();
+  return "${a}-${b}-${$}";
+}
+
+sub tmpname {
+  return "/tmp/lx-office-tmp-" . unique_id();
+}
+
 sub retrieve_parts {
   $main::lxdebug->enter_sub();
 
 
   $main::lxdebug->enter_sub();
 
   my ($self, $myconfig, $form) = @_;
-  my $rc;
+  my @rc;
 
   if ($form->{exporttype} == 0) {
-    $rc = &kne_buchungsexport($myconfig, $form);
+    @rc = &kne_buchungsexport($myconfig, $form);
   } else {
-    $rc = &kne_stammdatenexport($myconfig, $form);
+    @rc = &kne_stammdatenexport($myconfig, $form);
   }
 
   $main::lxdebug->leave_sub();
 
-  return $rc;
+  return @rc;
 }
 
 sub obe_export {
   $to   =~ s/ //g;
 
   if ($from ne "") {
-    my ($fday, $fmonth, $fyear) = split /\./, $from;
+    my ($fday, $fmonth, $fyear) = split(/\./, $from);
     if (length($fmonth) < 2) {
       $fmonth = "0" . $fmonth;
     }
   $header .= $from;
 
   if ($to ne "") {
-    my ($tday, $tmonth, $tyear) = split /\./, $to;
+    my ($tday, $tmonth, $tyear) = split(/\./, $to);
     if (length($tmonth) < 2) {
       $tmonth = "0" . $tmonth;
     }
 
   my ($date, $six) = @_;
 
-  ($day, $month, $year) = split /\./, $date;
+  ($day, $month, $year) = split(/\./, $date);
 
   if ($day =~ /^0/) {
     $day = substr($day, 1, 1);
   my ($umsatz, $stellen) = @_;
 
   $umsatz =~ s/-//;
-  ($vorkomma, $nachkomma) = split /\./, $umsatz;
+  ($vorkomma, $nachkomma) = split(/\./, $umsatz);
   $umsatz = "";
   if ($stellen > 0) {
     for ($i = $stellen; $i >= $stellen + 2 - length($vorkomma); $i--) {
 
   my ($myconfig, $form) = @_;
 
-  my $export_path = "datev/";
+  my @filenames;
+
+  my $export_path = $main::userspath . "/";
   my $filename    = "ED00000";
   my $evfile      = "EV01";
   my @ed_versionsets;
     my $buchungssatz    = "";
     $filename++;
     my $ed_filename = $export_path . $filename;
+    push(@filenames, $filename);
     open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
     $header = &make_kne_data_header($myconfig, $form, $fromto);
     $remaining_bytes -= length($header);
   #Make EV Verwaltungsdatei
   $ev_header = &make_ev_header($form, $fileno);
   $ev_filename = $export_path . $evfile;
+  push(@filenames, $evfile);
   open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
   print(EV $ev_header);
 
     print(EV $ed_versionset[$file]);
   }
   close(EV);
-  print qq|<br>Done. <br></body>
-</html>
+  print qq|<br>Done. <br>
 |;
   ###
   $main::lxdebug->leave_sub();
+
+  return @filenames;
 }
 
 sub kne_stammdatenexport {
   my ($myconfig, $form) = @_;
   $form->{abrechnungsnr} = "99";
 
-  my $export_path = "datev/";
+  $form->header;
+  print qq|
+  <html>
+  <body>Export in Bearbeitung<br>
+|;
+
+  my @filenames;
+
+  my $export_path = $main::userspath . "/";
   my $filename    = "ED00000";
   my $evfile      = "EV01";
   my @ed_versionsets;
   my $buchungssatz    = "";
   $filename++;
   my $ed_filename = $export_path . $filename;
+  push(@filenames, $filename);
   open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
   $header = &make_kne_data_header($myconfig, $form, "");
   $remaining_bytes -= length($header);
 
   $ev_header = &make_ev_header($form, $fileno);
   $ev_filename = $export_path . $evfile;
+  push(@filenames, $evfile);
   open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
   print(EV $ev_header);
 
   $dbh->disconnect;
   ###
 
+  print qq|<br>Done. <br>
+|;
+
   $main::lxdebug->leave_sub();
+
+  return @filenames;
 }
 
 1;
 
--- /dev/null
+package SL::DBUpgrade2;
+
+require Exporter;
+@ISA = qw(Exporter);
+
+@EXPORT = qw(parse_dbupdate_controls sort_dbupdate_controls);
+
+sub parse_dbupdate_controls {
+  $main::lxdebug->enter_sub();
+
+  my ($form, $dbdriver) = @_;
+
+  my $locale = $main::locale;
+
+  local *IN;
+  my %all_controls;
+
+  my $path = "sql/${dbdriver}-upgrade2";
+
+  foreach my $file_name (<$path/*.sql>, <$path/*.pl>) {
+    next unless (open(IN, $file_name));
+
+    my $file = $file_name;
+    $file =~ s|.*/||;
+
+    my $control = {
+      "priority" => 1000,
+      "depends" => [],
+    };
+
+    while (<IN>) {
+      chomp();
+      next unless (/^(--|\#)\s*\@/);
+      s/^(--|\#)\s*\@//;
+      s/\s*$//;
+      next if ($_ eq "");
+
+      my @fields = split(/\s*:\s*/, $_, 2);
+      next unless (scalar(@fields) == 2);
+
+      if ($fields[0] eq "depends") {
+        push(@{$control->{"depends"}}, split(/\s+/, $fields[1]));
+      } else {
+        $control->{$fields[0]} = $fields[1];
+      }
+    }
+
+    _control_error($form, $file_name,
+                   $locale->text("Missing 'tag' field."))
+      unless ($control->{"tag"});
+
+    _control_error($form, $file_name,
+                   $locale->text("The 'tag' field must only consist of " .
+                                 "alphanumeric characters or the carachters " .
+                                 "- _ ( )"))
+      if ($control->{"tag"} =~ /[^a-zA-Z0-9_\(\)\-]/);
+
+    _control_error($form, $file_name,
+                   sprintf($locale->text("More than one control file " .
+                                         "with the tag '%s' exist."),
+                           $control->{"tag"}))
+      if (defined($all_controls{$control->{"tag"}}));
+
+    _control_error($form, $file_name,
+                   sprintf($locale->text("Missing 'description' field.")))
+      unless ($control->{"description"});
+
+    $control->{"priority"} *= 1;
+    $control->{"priority"} = 1000 unless ($control->{"priority"});
+
+    $control->{"file"} = $file;
+
+    map({ delete($control->{$_}); } qw(depth applied));
+
+    $all_controls{$control->{"tag"}} = $control;
+
+    close(IN);
+  }
+
+  foreach my $control (values(%all_controls)) {
+    foreach my $dependency (@{$control->{"depends"}}) {
+      _control_error($form, $control->{"file"},
+                     sprintf($locale->text("Unknown dependency '%s'."),
+                             $dependency))
+        if (!defined($all_controls{$dependency}));
+    }
+
+    map({ $_->{"loop"} = 0; } values(%all_controls));
+    _check_for_loops($form, $control->{"file"}, \%all_controls,
+                     $control->{"tag"});
+  }
+
+  map({ _dbupdate2_calculate_depth(\%all_controls, $_->{"tag"}) }
+      values(%all_controls));
+
+  $main::lxdebug->leave_sub();
+
+  return \%all_controls;
+}
+
+sub _check_for_loops {
+  my ($form, $file_name, $controls, $tag, @path) = @_;
+
+  push(@path, $tag);
+
+  _control_error($form, $file_name,
+                 $main::locale->text("Dependency loop detected:") .
+                 " " . join(" -> ", @path))
+    if ($controls->{$tag}->{"loop"});
+
+  $controls->{$tag}->{"loop"} = 1;
+  map({ _check_for_loops($form, $file_name, $controls, $_, @path); }
+      @{$controls->{$tag}->{"depends"}});
+}
+
+sub _control_error {
+  my ($form, $file_name, $message) = @_;
+
+  my $form = $main::form;
+  my $locale = $main::locale;
+
+  $form->error(sprintf($locale->text("Error in database control file '%s': %s"),
+                       $file_name, $message));
+}
+
+sub _dbupdate2_calculate_depth {
+  $main::lxdebug->enter_sub();
+
+  my ($tree, $tag) = @_;
+
+  my $node = $tree->{$tag};
+
+  return $main::lxdebug->leave_sub() if (defined($node->{"depth"}));
+
+  my $max_depth = 0;
+
+  foreach $tag (@{$node->{"depends"}}) {
+    _dbupdate2_calculate_depth($tree, $tag);
+    my $value = $tree->{$tag}->{"depth"};
+    $max_depth = $value if ($value > $max_depth);
+  }
+
+  $node->{"depth"} = $max_depth + 1;
+
+  $main::lxdebug->leave_sub();
+}
+
+sub sort_dbupdate_controls {
+  return
+    sort({ $a->{"depth"} != $b->{"depth"} ? $a->{"depth"} <=> $b->{"depth"} :
+             $a->{"priority"} != $b->{"priority"} ?
+             $a->{"priority"} <=> $b->{"priority"} :
+             $a->{"tag"} cmp $b->{"tag"} } values(%{$_[0]}));
+}
+
+
+1;
 
   $self->{action} = lc $self->{action};
   $self->{action} =~ s/( |-|,|\#)/_/g;
 
-  $self->{version}   = "2.4.0";
+  $self->{version}   = "2.4.1";
 
   $main::lxdebug->leave_sub();
 
 sub header {
   $main::lxdebug->enter_sub();
 
-  my ($self) = @_;
+  my ($self, $extra_code) = @_;
 
   if ($self->{header}) {
     $main::lxdebug->leave_sub();
  |;
     }
 
+    $self->{favicon}    = "favicon.ico" unless $self->{favicon};
+
     if ($self->{favicon} && (-f "$self->{favicon}")) {
       $favicon =
         qq|<LINK REL="shortcut icon" HREF="$self->{favicon}" TYPE="image/x-icon">
   
   </script>
 
+  $extra_code
 </head>
 
 |;
   $self->{"notes"} = $self->{ $self->{"formname"} . "notes" };
 
   map({ $self->{"employee_${_}"} = $myconfig->{$_}; }
-      qw(email tel fax name signature company address businessnumber));
+      qw(email tel fax name signature company address businessnumber
+         co_ustid taxnumber duns));
+  map({ $self->{"employee_${_}"} =~ s/\\n/\n/g; }
+      qw(company address signature));
 
   $self->{copies} = 1 if (($self->{copies} *= 1) <= 0);
 
   }
 
   close(OUT);
-  
-  use Data::Dumper;
-  #print(STDERR Dumper($self));
 
   if ($template->uses_temp_file() || $self->{media} eq 'email') {
 
 
       } else {
 
-        @{ $mail->{attachments} } = ($self->{tmpfile}) unless ($form->{do_not_attach});
+        @{ $mail->{attachments} } = ($self->{tmpfile}) unless ($self->{do_not_attach});
 
         $mail->{message}       =~ s/\r\n/\n/g;
         $myconfig->{signature} =~ s/\\n/\n/g;
           open(OUT, $self->{OUT})
             or $self->error($self->cleanup . "$self->{OUT} : $!");
         } else {
-
+          $self->{attachment_filename} = $self->{tmpfile} if ($self->{attachment_filename} eq '');
           # launch application
           print qq|Content-Type: | . $template->get_mime_type() . qq|
-Content-Disposition: attachment; filename="$self->{tmpfile}"
+Content-Disposition: attachment; filename="$self->{attachment_filename}"
 Content-Length: $numbytes
 
 |;
   
     ($self->{terms_netto}, $self->{terms_skonto}, $self->{percent_skonto}, $self->{payment_terms}) = $sth->fetchrow_array;
 
+    if ($transdate eq "") {
+      if ($self->{invdate}) {
+        $transdate = $self->{invdate};
+      } else {
+        $transdate = $self->{transdate};
+      }
+    }
+
     $sth->finish;
     my $query = qq|SELECT date '$transdate' + $self->{terms_netto} AS netto_date,date '$transdate' + $self->{terms_skonto} AS skonto_date  FROM payment_terms
                   LIMIT 1|;
     ($self->{netto_date}, $self->{skonto_date}) = $sth->fetchrow_array;
     $sth->finish;
 
-    $self->{skonto_amount} = $self->format_amount($myconfig, ($self->parse_amount($myconfig, $self->{subtotal}) * $self->{percent_skonto}), 2);
+    my $total = ($self->{invtotal}) ? $self->{invtotal} : $self->{ordtotal};
+
+    $self->{skonto_amount} = $self->format_amount($myconfig, ($self->parse_amount($myconfig, $total) * $self->{percent_skonto}), 2);
 
     $self->{payment_terms} =~ s/<%netto_date%>/$self->{netto_date}/g;
     $self->{payment_terms} =~ s/<%skonto_date%>/$self->{skonto_date}/g;
     $self->{payment_terms} =~ s/<%skonto_amount%>/$self->{skonto_amount}/g;
+    $self->{payment_terms} =~ s/<%total%>/$self->{total}/g;
+    $self->{payment_terms} =~ s/<%invtotal%>/$self->{invtotal}/g;
+    $self->{payment_terms} =~ s/<%currency%>/$self->{currency}/g;
+    $self->{payment_terms} =~ s/<%terms_netto%>/$self->{terms_netto}/g;
+    $self->{payment_terms} =~ s/<%account_number%>/$self->{account_number}/g;
+    $self->{payment_terms} =~ s/<%bank%>/$self->{bank}/g;
+    $self->{payment_terms} =~ s/<%bank_code%>/$self->{bank_code}/g;
 
     $dbh->disconnect;
   }
     my $sth = $dbh->prepare($query);
     $sth->execute || $self->dberror($query);
     $ref = $sth->fetchrow_hashref(NAME_lc);
-    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    map { $self->{$_} = $ref->{$_} } keys %$ref;
     $sth->finish;  
     $dbh->disconnect;
   }
   $main::lxdebug->leave_sub();
 }
 
+sub get_duedate {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig) = @_;
+
+  my $dbh = $self->dbconnect($myconfig);
+  my $query = qq|SELECT current_date+terms_netto FROM payment_terms
+                 WHERE id = '$self->{payment_id}'|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  ($self->{duedate}) = $sth->fetchrow_array;
+
+  $sth->finish;
+
+  $main::lxdebug->leave_sub();
+}
+
 # get other contact for transaction and form - html/tex
 sub get_contact {
   $main::lxdebug->enter_sub();
               FROM language
              ORDER BY 1|;
   $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
     push @{ $self->{languages} }, $ref;
               FROM printers
              ORDER BY 1|;
   $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
     push @{ $self->{printers} }, $ref;
               FROM payment_terms
              ORDER BY 1|;
   $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
     push @{ $self->{payment_terms} }, $ref;
               FROM language
              ORDER BY 1|;
   my $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
     push @{ $self->{languages} }, $ref;
               FROM printers
              ORDER BY 1|;
   $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
     push @{ $self->{printers} }, $ref;
               FROM payment_terms
              ORDER BY 1|;
   $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
     push @{ $self->{payment_terms} }, $ref;
   $query = qq|SELECT id, description
               FROM buchungsgruppen|;
   $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
   $self->{BUCHUNGSGRUPPEN} = [];
   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
   $query = qq|SELECT id, description
               FROM tax_zones|;
   $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute || $self->dberror($query);
 
 
   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
   return ($yy, $mm, $dd);
 }
 
+sub reformat_date {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $date, $output_format, $longformat) = @_;
+
+  $main::lxdebug->leave_sub() and return "" unless ($date);
+
+  my ($yy, $mm, $dd) = $self->parse_date($myconfig, $date);
+
+  $output_format =~ /d+/;
+  substr($output_format, $-[0], $+[0] - $-[0]) =
+    sprintf("%0" . (length($&)) . "d", $dd);
+
+  $output_format =~ /m+/;
+  substr($output_format, $-[0], $+[0] - $-[0]) =
+    sprintf("%0" . (length($&)) . "d", $mm);
+
+  $output_format =~ /y+/;
+  if (length($&) == 2) {
+    $yy -= $yy >= 2000 ? 2000 : 1900;
+  }
+  substr($output_format, $-[0], $+[0] - $-[0]) =
+    sprintf("%0" . (length($&)) . "d", $yy);
+
+  $main::lxdebug->leave_sub();
+
+  return $output_format;
+}
+
 1;
 
     # retrieve individual rows
     $query = qq|SELECT c.accno, t.taxkey AS accnotaxkey, a.amount, a.memo,
                 a.transdate, a.cleared, a.project_id, p.projectnumber,(SELECT p.projectnumber FROM project p
-                WHERE a.project_id = p.id) AS projectnumber, a.taxkey, t.rate AS taxrate, t.id, (SELECT c1.accno FROM chart c1, tax t1 WHERE t1.id=t.id AND c1.id=t.chart_id) AS taxaccno, t.id AS tax_id
+                WHERE a.project_id = p.id) AS projectnumber, a.taxkey, t.rate AS taxrate, t.id, (SELECT c1.accno FROM chart c1, tax t1 WHERE t1.id=t.id AND c1.id=t.chart_id) AS taxaccno, (SELECT tk.tax_id FROM taxkeys tk WHERE tk.chart_id =a.chart_id AND tk.startdate<=a.transdate ORDER BY tk.startdate desc LIMIT 1) AS tax_id
                FROM acc_trans a
                JOIN chart c ON (c.id = a.chart_id)
                LEFT JOIN project p ON (p.id = a.project_id)
-                LEFT JOIN tax t ON (t.id=(SELECT tk.tax_id from taxkeys tk WHERE (tk.taxkey_id=a.taxkey) AND ((CASE WHEN a.chart_id IN (SELECT chart_id FROM taxkeys WHERE taxkey_id=a.taxkey) THEN tk.chart_id=a.chart_id ELSE 1=1 END) OR (c.link='%tax%')) AND startdate <=a.transdate ORDER BY startdate DESC LIMIT 1)) 
+                LEFT JOIN tax t ON (t.id=(SELECT tk.tax_id from taxkeys tk WHERE (tk.taxkey_id=a.taxkey) AND ((CASE WHEN a.chart_id IN (SELECT chart_id FROM taxkeys WHERE taxkey_id=a.taxkey) THEN tk.chart_id=a.chart_id ELSE 1=1 END) OR (c.link LIKE '%tax%')) AND startdate <=a.transdate ORDER BY startdate DESC LIMIT 1)) 
                 WHERE a.trans_id = $form->{id}
                AND a.fx_transaction = '0'
                ORDER BY a.oid,a.transdate|;
 
-
     $sth = $dbh->prepare($query);
     $sth->execute || $form->dberror($query);
 
+    $form->{GL} = [];
     while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
       push @{ $form->{GL} }, $ref;
     }
     $query = qq| SELECT * FROM tax t order by t.taxkey|;
     $sth   = $dbh->prepare($query);
     $sth->execute || $form->dberror($query);
-    $form->{TAX} = ();
+    $form->{TAX} = [];
     while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
       push @{ $form->{TAX} }, $ref;
     }
 
     $sth->finish;
   } else {
-    $query = "SELECT current_date AS transdate, closedto, revtrans
-              FROM defaults";
-    $sth = $dbh->prepare($query);
-    $sth->execute || $form->dberror($query);
-
-    ($form->{transdate}, $form->{closedto}, $form->{revtrans}) =
-      $sth->fetchrow_array;
+    $query = "SELECT closedto, revtrans FROM defaults";
+    ($form->{closedto}, $form->{revtrans}) = $dbh->selectrow_array($query);
+    $query =
+      "SELECT COALESCE(" .
+      "  (SELECT transdate FROM gl WHERE id = " .
+      "    (SELECT MAX(id) FROM gl) LIMIT 1), " .
+      "  current_date)";
+    ($form->{transdate}) = $dbh->selectrow_array($query);
 
     # get tax description
     $query = qq| SELECT * FROM tax t order by t.taxkey|;
 
   }
   $sth->finish;
 
-  if ($form->{id}) {
-    $query = qq|SELECT weightunit
-                FROM defaults|;
-    $sth = $dbh->prepare($query);
-    $sth->execute || $form->dberror($query);
-
-    ($form->{weightunit}) = $sth->fetchrow_array;
-    $sth->finish;
-
-  } else {
-    $query = qq|SELECT weightunit, current_date
-                FROM defaults|;
+  if (!$form->{id}) {
+    $query = qq|SELECT current_date FROM defaults|;
     $sth = $dbh->prepare($query);
     $sth->execute || $form->dberror($query);
 
-    ($form->{weightunit}, $form->{priceupdate}) = $sth->fetchrow_array;
+    ($form->{priceupdate}) = $sth->fetchrow_array;
     $sth->finish;
   }
 
     } else {
       $transdate = $form->{deliverydate};
     }
+  } elsif ($form->{type} eq "credit_note") {
+    $transdate = $form->{invdate};
   } else {
     $transdate = $form->{transdate};
   }
 
   if (!$ref) {
     $dbh->disconnect();
-    return $lxdebug->leave_sub();
+    return $main::lxdebug->leave_sub();
   }
 
   $ref->{"inventory_accno_id"} = undef unless ($ref->{"is_part"});
   $sth->finish();
   $dbh->disconnect();
 
-  return $main::lxdebug->leave_sub() unless ($ref);
+  unless ($ref) {
+    $main::lxdebug->leave_sub();
+    return;
+  }
 
   $form->{"taxaccounts_$index"} = $ref->{"accno"};
   if ($form->{"taxaccounts"} !~ /$ref->{accno}/) {
 #                           " || taxaccounts_$index " . $form->{"taxaccounts_$index"} .
 #                           " || taxaccounts " . $form->{"taxaccounts"});
 
-  $sth->finish();
-
   $main::lxdebug->leave_sub();
 }
 1;
 
     if ($form->{storno}) {
       $form->{"qty_$i"} *= -1;
     }
+
+    if ($main::eur) {
+      $form->{"inventory_accno_$i"} = $form->{"expense_accno_$i"};
+    }
     
     if ($form->{"qty_$i"} != 0) {
 
       $form->{transdate} ? $dbh->quote($form->{transdate}) : "current_date";
   }
 
-  my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice,
+  my $query = qq|SELECT p.id, p.partnumber, p.description, p.lastcost AS sellprice,
                         p.listprice, p.inventory_accno_id,
                         c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid,
                        c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate)  - c2.valid_from as income_valid,
 sub vendor_details {
   $main::lxdebug->enter_sub();
 
-  my ($self, $myconfig, $form) = @_;
+  my ($self, $myconfig, $form, @wanted_vars) = @_;
 
   # connect to database
   my $dbh = $form->dbconnect($myconfig);
 
   # remove id and taxincluded before copy back
   delete @$ref{qw(id taxincluded)};
+
+  if (scalar(@wanted_vars) > 0) {
+    my %h_wanted_vars;
+    map({ $h_wanted_vars{$_} = 1; } @wanted_vars);
+    map({ delete($ref->{$_}) unless ($h_wanted_vars{$_}); } keys(%{$ref}));
+  }
+
   map { $form->{$_} = $ref->{$_} } keys %$ref;
 
   $sth->finish;
 
 sub customer_details {
   $main::lxdebug->enter_sub();
 
-  my ($self, $myconfig, $form) = @_;
+  my ($self, $myconfig, $form, @wanted_vars) = @_;
 
   # connect to database
   my $dbh = $form->dbconnect($myconfig);
 
   # remove id and taxincluded before copy back
   delete @$ref{qw(id taxincluded)};
+
+  if (scalar(@wanted_vars) > 0) {
+    my %h_wanted_vars;
+    map({ $h_wanted_vars{$_} = 1; } @wanted_vars);
+    map({ delete($ref->{$_}) unless ($h_wanted_vars{$_}); } keys(%{$ref}));
+  }
+
   map { $form->{$_} = $ref->{$_} } keys %$ref;
   $sth->finish;
 
                                 $baseqty * -1)
             unless $form->{shipped};
 
-          $allocated = &cogs($dbh, $form, $form->{"id_$i"}, $baseqty, $basefactor);
+          $allocated = &cogs($dbh, $form, $form->{"id_$i"}, $baseqty, $basefactor, $i);
         }
       }
 
 sub cogs {
   $main::lxdebug->enter_sub();
 
-  my ($dbh, $form, $id, $totalqty, $basefactor) = @_;
-
+  my ($dbh, $form, $id, $totalqty, $basefactor, $row) = @_;
+  $form->{taxzone_id} *=1;
+  my $transdate = ($form->{invdate}) ? "'$form->{invdate}'" : "current_date";
   my $query = qq|SELECT i.id, i.trans_id, i.base_qty, i.allocated, i.sellprice,
-                   (SELECT c.accno FROM chart c
-                   WHERE p.inventory_accno_id = c.id) AS inventory_accno,
-                  (SELECT c.accno FROM chart c
-                   WHERE p.expense_accno_id = c.id) AS expense_accno
+                        c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid,
+                       c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate)  - c2.valid_from as income_valid,
+                       c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid
                  FROM invoice i, parts p
+                  LEFT JOIN chart c1 ON ((select inventory_accno_id from buchungsgruppen where id=p.buchungsgruppen_id) = c1.id)
+                  LEFT JOIN chart c2 ON ((select income_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c2.id)
+                  LEFT JOIN chart c3 ON ((select expense_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c3.id)
                  WHERE i.parts_id = p.id
                  AND i.parts_id = $id
                  AND (i.base_qty + i.allocated) < 0
     # sellprice is the cost of the item
     $linetotal = $form->round_amount(($ref->{sellprice} * $qty) / $basefactor, 2);
 
-    if (!$eur) {
-
+    if (!$main::eur) {
+      $ref->{expense_accno} = ($form->{"expense_accno_$row"}) ? $form->{"expense_accno_$row"} : $ref->{expense_accno};
       # add to expense
       $form->{amount}{ $form->{id} }{ $ref->{expense_accno} } += -$linetotal;
       $form->{expense_inventory} .= " " . $ref->{expense_accno};
-
+      $ref->{inventory_accno} = ($form->{"inventory_accno_$row"}) ? $form->{"inventory_accno_$row"} : $ref->{inventory_accno};
       # deduct inventory
       $form->{amount}{ $form->{id} }{ $ref->{inventory_accno} } -= -$linetotal;
       $form->{expense_inventory} .= " " . $ref->{inventory_accno};
 
   # add other params
   foreach my $key (keys %{ $self->{$item} }) {
     $str .= "&" . $form->escape($key, 1) . "=";
-    ($value, $conf) = split /=/, $self->{$item}{$key}, 2;
+    ($value, $conf) = split(/=/, $self->{$item}{$key}, 2);
     $value = $myconfig->{$value} . "/$conf" if ($conf);
     $str .= $form->escape($value, 1);
   }
   return $str;
 }
 
+sub menuitem_v3 {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form, $item, $other) = @_;
+
+  my $module = $form->{script};
+  my $action = "section_menu";
+  my $target = "";
+
+  if ($self->{$item}{module}) {
+    $module = $self->{$item}{module};
+  }
+  if ($self->{$item}{action}) {
+    $action = $self->{$item}{action};
+  }
+  if ($self->{$item}{target}) {
+    $target = $self->{$item}{target};
+  }
+
+  my $level = $form->escape($item);
+
+  my $str = qq|<a href="$module?action=| . $form->escape($action) .
+    qq|&level=| . $form->escape($level);
+  map({ $str .= "&${_}=" . $form->escape($form->{$_}); } qw(path login password));
+
+  my @vars = qw(module action target href);
+
+  if ($self->{$item}{href}) {
+    $str  = qq|<a href=$self->{$item}{href}|;
+    @vars = qw(module target href);
+  }
+
+  map { delete $self->{$item}{$_} } @vars;
+
+  # add other params
+  foreach my $key (keys %{ $self->{$item} }) {
+    $str .= "&" . $form->escape($key, 1) . "=";
+    ($value, $conf) = split(/=/, $self->{$item}{$key}, 2);
+    $value = $myconfig->{$value} . "/$conf" if ($conf);
+    $str .= $form->escape($value, 1);
+  }
+
+  $str .= '"';
+
+  if ($target) {
+    $str .= qq| target="| . $form->quote($target) . qq|"|;
+  }
+
+  if ($other) {
+    foreach my $key (keys(%{$other})) {
+      $str .= qq| ${key}="| . $form->quote($other->{$key}) . qq|"|;
+    }
+  }
+
+  $str .= ">";
+
+  $main::lxdebug->leave_sub();
+
+  return $str;
+}
+
 sub menuitemNew {
   my ($self, $myconfig, $form, $item) = @_;
 
   # add other params
   foreach my $key (keys %{ $self->{$item} }) {
     $str .= "&" . $form->escape($key, 1) . "=";
-    ($value, $conf) = split /=/, $self->{$item}{$key}, 2;
+    ($value, $conf) = split(/=/, $self->{$item}{$key}, 2);
     $value = $myconfig->{$value} . "/$conf" if ($conf);
     $str .= $form->escape($value, 1);
   }
     @menu = grep { /^${menulevel}--/ } @{ $self->{ORDER} };
   }
 
-  my @a    = split /;/, $myconfig->{acs};
+  my @a    = split(/;/, $myconfig->{acs});
   my $excl = ();
 
   # remove --AR, --AP from array
 
 package OE;
 
 use SL::AM;
+use SL::DBUtils;
 
 sub transactions {
   $main::lxdebug->enter_sub();
   $main::lxdebug->leave_sub();
 }
 
+sub close_order {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  $main::lxdebug->leave_sub() unless ($form->{"id"});
+
+  my $dbh = $form->dbconnect($myconfig);
+  do_query($form, $dbh, qq|UPDATE oe SET closed = TRUE where ordnumber = ?|,
+           $form->{"id"});
+  $dbh->disconnect;
+
+  $main::lxdebug->leave_sub();
+}
+
 sub delete {
   $main::lxdebug->enter_sub();
 
       $sameitem = $item->[1];
 
       map { push(@{ $form->{$_} }, "") }
-        qw(runningnumber number qty ship unit bin partnotes serialnumber reqdate sellprice listprice netprice discount linetotal);
+        qw(runningnumber number qty ship unit bin partnotes
+           serialnumber reqdate sellprice listprice netprice
+           discount p_discount linetotal);
     }
 
     $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
         while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
           if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
             map { push(@{ $form->{$_} }, "") }
-              qw(runningnumber ship bin serialnumber number unit bin qty reqdate sellprice listprice netprice discount linetotal nodiscount_linetotal);
+              qw(runningnumber ship bin serialnumber number unit bin qty 
+                 reqdate sellprice listprice netprice discount p_discount
+                 linetotal nodiscount_linetotal);
             $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
             push(@{ $form->{description} }, $sameitem);
           }
                  . qq|, $ref->{partnumber}, $ref->{description}|);
 
           map { push(@{ $form->{$_} }, "") }
-            qw(number unit qty runningnumber ship bin serialnumber reqdate sellprice listprice netprice discount linetotal nodiscount_linetotal);
+            qw(number unit qty runningnumber ship bin serialnumber reqdate 
+               sellprice listprice netprice discount p_discount linetotal 
+               nodiscount_linetotal);
 
         }
         $sth->finish;
 
       $sum += $form->parse_amount($self->{"myconfig"},
                                   $form->{"linetotal"}->[$i]);
     }
-
+    
+    $form->{"cumulatelinetotal"}[$i] = $form->format_amount($self->{"myconfig"}, $sum, 2);
+    
     my $new_text = $self->parse_block($text, (@indices, $i));
     return undef unless (defined($new_text));
     $new_contents .= $start_tag . $new_text . $end_tag;
 sub get_mime_type() {
   my ($self) = @_;
 
-  if ($self->{"form"}->{"format"} =~ /xml/i) {
+  if ($self->{"form"}->{"format"} =~ /elsterwinston/i) {
     return "application/xml ";
+  } elsif ($self->{"form"}->{"format"} =~ /elstertaxbird/i) {
+    return "application/x-taxbird";
   } else {
-    return "text/xml";
+    return "text";
   }
 }
 
 sub uses_temp_file {
-#  my ($self) = @_;
-  # no tempfile needet for XML Output
+  # tempfile needet for XML Output
   return 1;
 }
 
 
 
   my $last_period     = 0;
   my $category        = "pos_ustva";
-  my @categories_cent = qw(511 861 36 80 971 931 98 96 53 74
+  my @category_cent = qw(511 861 36 80 971 931 98 96 53 74
     85 65 66 61 62 67 63 64 59 69 39 83
     Z43 Z45 Z53 Z62 Z65 Z67);
 
-  my @categories_euro = qw(41 44 49 43 48 51 86 35 77 76 91 97 93
+  my @category_euro = qw(41 44 49 43 48 51 86 35 77 76 91 97 93
     95 94 42 60 45 52 73 84);
 
   $form->{decimalplaces} *= 1;
 
-  foreach $item (@categories_cent) {
+  foreach $item (@category_cent) {
     $form->{"$item"} = 0;
   }
-  foreach $item (@categories_euro) {
+  foreach $item (@category_euro) {
     $form->{"$item"} = 0;
   }
 
   #
   # Berechnung der USTVA Formularfelder
   #
+
   $form->{"51r"} = $form->{"511"};
   $form->{"86r"} = $form->{"861"};
   $form->{"97r"} = $form->{"971"};
   $form->{"93r"} = $form->{"931"};
   $form->{"Z43"} =
-    $form->{"511"} + $form->{"861"} + $form->{"36"} + $form->{"80"} +
-    $form->{"971"} + $form->{"931"} + $form->{"96"} + $form->{"98"};
+  $form->{"511"} + $form->{"861"} + $form->{"36"} + $form->{"80"} +
+  $form->{"971"} + $form->{"931"} + $form->{"96"} + $form->{"98"};
   $form->{"Z45"} = $form->{"Z43"};
   $form->{"Z53"} = $form->{"Z43"};
   $form->{"Z62"} =
-    $form->{"Z43"} - $form->{"66"} - $form->{"61"} - $form->{"62"} -
-    $form->{"63"} - $form->{"64"} - $form->{"59"};
+  $form->{"Z43"} - $form->{"66"} - $form->{"61"} - $form->{"62"} -
+  $form->{"63"} - $form->{"64"} - $form->{"59"};
   $form->{"Z65"} = $form->{"Z62"} - $form->{"69"};
   $form->{"83"}  = $form->{"Z65"} - $form->{"39"};
-
-  foreach $item (@categories_cent) {
-    $form->{$item} =
-      $form->format_amount($myconfig, $form->{$item}, '2', '0');
-  }
-
-  foreach $item (@categories_euro) {
-    $form->{$item} =
-      $form->format_amount($myconfig, $form->{$item}, '0', '0');
-  }
-
+  # Hier fehlen moeglicherweise noch einige Berechnungen!
+  
   $dbh->disconnect;
 
   $main::lxdebug->leave_sub();
 
   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
 # Bug 365 solved?!
-#    if ($ref->{amount} < 0) {
-      $ref->{amount} *= -1;
-#    }
+   $ref->{amount} *= -1;
     if ($category eq "pos_bwa") {
       if ($last_period) {
         $form->{ $ref->{$category} }{kumm} += $ref->{amount};
 
 
 package User;
 
+use SL::DBUpgrade2;
+
 sub new {
   $main::lxdebug->enter_sub();
 
                  '$myconfig{tel}', 'user')|;
       $dbh->do($query);
     }
+
+    $self->create_schema_info_table($form, $dbh);
+
     $dbh->disconnect;
 
     $rc = 0;
 
-    if (&update_available($myconfig{"dbdriver"}, $dbversion)) {
+    my $controls =
+      parse_dbupdate_controls($form, $myconfig{"dbdriver"});
+
+    map({ $form->{$_} = $myconfig{$_} }
+        qw(dbname dbhost dbport dbdriver dbuser dbpasswd dbconnect));
 
-      map { $form->{$_} = $myconfig{$_} }
-        qw(dbname dbhost dbport dbdriver dbuser dbpasswd dbconnect);
+    if (update_available($myconfig{"dbdriver"}, $dbversion) ||
+        update2_available($form, $controls)) {
 
       $form->{"stylesheet"} = "lx-office-erp.css";
       $form->{"title"} = $main::locale->text("Dataset upgrade");
       }
 
       # update the tables
-      open FH, ">$userspath/nologin" or die "
-$!";
+      open(FH, ">$userspath/nologin") or die("$!");
 
       # required for Oracle
       $form->{dbdefault} = $sid;
       $SIG{QUIT} = 'IGNORE';
 
       $self->dbupdate($form);
+      $self->dbupdate2($form, $controls);
 
       # remove lock file
-      unlink "$userspath/nologin";
+      unlink("$userspath/nologin");
 
-      print($form->parse_html_template("dbupgrade/footer"));
+      my $menufile =
+        $self->{"menustyle"} eq "v3" ? "menuv3.pl" :
+        $self->{"menustyle"} eq "neu" ? "menunew.pl" :
+        "menu.pl";
+
+      print($form->parse_html_template("dbupgrade/footer",
+                                       { "menufile" => $menufile }));
 
       $rc = -2;
 
 
   my ($self, $form) = @_;
 
+  $form->{sid} = $form->{dbdefault};
+  &dbconnect_vars($form, $form->{dbdefault});
+  my $dbh =
+    DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
+    or $form->dberror;
+
   my %dbcreate = (
     'Pg'     => qq|CREATE DATABASE "$form->{db}"|,
     'Oracle' =>
       qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|
   );
 
-  $dbcreate{Pg} .= " WITH ENCODING = '$form->{encoding}'" if $form->{encoding};
+  my %dboptions = (
+    'Pg' => [],
+  );
+
+  push(@{$dboptions{"Pg"}}, "ENCODING = " . $dbh->quote($form->{"encoding"}))
+    if ($form->{"encoding"});
+  if ($form->{"dbdefault"}) {
+    my $dbdefault = $form->{"dbdefault"};
+    $dbdefault =~ s/[^a-zA-Z0-9_\-]//g;
+    push(@{$dboptions{"Pg"}}, "TEMPLATE = $dbdefault");
+  }
 
-  $form->{sid} = $form->{dbdefault};
-  &dbconnect_vars($form, $form->{dbdefault});
-  my $dbh =
-    DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
-    or $form->dberror;
   my $query = qq|$dbcreate{$form->{dbdriver}}|;
+  $query .= " WITH " . join(" ", @{$dboptions{"Pg"}}) if (@{$dboptions{"Pg"}});
+
   $dbh->do($query) || $form->dberror($query);
 
   if ($form->{dbdriver} eq 'Oracle') {
 sub process_query {
   $main::lxdebug->enter_sub();
 
-  my ($self, $form, $dbh, $filename, $version) = @_;
+  my ($self, $form, $dbh, $filename, $version_or_control) = @_;
 
   #  return unless (-f $filename);
 
     }
   }
 
-  if ($version) {
-    $dbh->do("UPDATE defaults SET version = " . $dbh->quote($version));
+  if (ref($version_or_control) eq "HASH") {
+    $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
+             $dbh->quote($version_or_control->{"tag"}) . ", " .
+             $dbh->quote($form->{"login"}) . ")");
+  } elsif ($version_or_control) {
+    $dbh->do("UPDATE defaults SET version = " .
+             $dbh->quote($version_or_control));
   }
   $dbh->commit();
 
 
   opendir SQLDIR, "sql/${dbdriver}-upgrade" or &error("", "sql/${dbdriver}-upgrade: $!");
   my @upgradescripts =
-    grep(/$form->{dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)/, readdir(SQLDIR));
+    grep(/$form->{dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir(SQLDIR));
   closedir SQLDIR;
 
   return ($#upgradescripts > -1);
 }
 
+sub create_schema_info_table {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $form, $dbh) = @_;
+
+  my $query = "SELECT tag FROM schema_info LIMIT 1";
+  if (!$dbh->do($query)) {
+    $query =
+      "CREATE TABLE schema_info (" .
+      "  tag text, " .
+      "  login text, " .
+      "  itime timestamp DEFAULT now(), " .
+      "  PRIMARY KEY (tag))";
+    $dbh->do($query) || $form->dberror($query);
+  }
+
+  $main::lxdebug->leave_sub();
+}
+
 sub dbupdate {
   $main::lxdebug->enter_sub();
 
       last if ($version < $mindb);
 
       # apply upgrade
-      $main::lxdebug->message(DEBUG2, "Appliying Update $upgradescript");
+      $main::lxdebug->message(DEBUG2, "Applying Update $upgradescript");
       if ($file_type eq "sql") {
         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} . "-upgrade/$upgradescript", $str_maxdb);
       } else {
   return $rc;
 }
 
+sub dbupdate2 {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $form, $controls) = @_;
+
+  $form->{sid} = $form->{dbdefault};
+
+  my @upgradescripts = ();
+  my ($query, $sth, $tag);
+  my $rc = -2;
+
+  @upgradescripts = sort_dbupdate_controls($controls);
+
+  foreach my $db (split / /, $form->{dbupdate}) {
+
+    next unless $form->{$db};
+
+    # strip db from dataset
+    $db =~ s/^db//;
+    &dbconnect_vars($form, $db);
+
+    my $dbh =
+      DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
+      or $form->dberror;
+
+    map({ $_->{"applied"} = 0; } @upgradescripts);
+
+    $query = "SELECT tag FROM schema_info";
+    $sth = $dbh->prepare($query);
+    $sth->execute() || $form->dberror($query);
+    while (($tag) = $sth->fetchrow_array()) {
+      $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
+    }
+    $sth->finish();
+
+    my $all_applied = 1;
+    foreach (@upgradescripts) {
+      if (!$_->{"applied"}) {
+        $all_applied = 0;
+        last;
+      }
+    }
+
+    next if ($all_applied);
+
+    foreach my $control (@upgradescripts) {
+      next if ($control->{"applied"});
+
+      $control->{"file"} =~ /\.(sql|pl)$/;
+      my $file_type = $1;
+
+      # apply upgrade
+      $main::lxdebug->message(DEBUG2, "Applying Update $control->{file}");
+      print($form->parse_html_template("dbupgrade/upgrade_message2",
+                                       $control));
+
+      if ($file_type eq "sql") {
+        $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
+                             "-upgrade2/$control->{file}", $control);
+      } else {
+        $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
+                                   "-upgrade2/$control->{file}", $control);
+      }
+    }
+
+    $rc = 0;
+    $dbh->disconnect;
+
+  }
+
+  $main::lxdebug->leave_sub();
+
+  return $rc;
+}
+
+sub update2_available {
+  $main::lxdebug->enter_sub();
+
+  my ($form, $controls) = @_;
+
+  map({ $_->{"applied"} = 0; } values(%{$controls}));
+
+  dbconnect_vars($form, $form->{"dbname"});
+
+  my $dbh =
+    DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) ||
+    $form->dberror;
+
+  my ($query, $tag, $sth);
+
+  $query = "SELECT tag FROM schema_info";
+  $sth = $dbh->prepare($query);
+  $sth->execute() || $form->dberror($query);
+  while (($tag) = $sth->fetchrow_array()) {
+    $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
+  }
+  $sth->finish();
+  $dbh->disconnect();
+
+  map({ $main::lxdebug->leave_sub() and return 1 if (!$_->{"applied"}) }
+      values(%{$controls}));
+
+  $main::lxdebug->leave_sub();
+  return 0;
+}
+
 sub create_config {
   $main::lxdebug->enter_sub();
 
     currency dateformat dbconnect dbdriver dbhost dbport dboptions
     dbname dbuser dbpasswd email fax name numberformat in_numberformat password
     printer role sid signature stylesheet tel templates vclimit angebote bestellungen rechnungen
-    anfragen lieferantenbestellungen einkaufsrechnungen steuernummer co_ustid duns menustyle);
+    anfragen lieferantenbestellungen einkaufsrechnungen taxnumber co_ustid duns menustyle
+    template_format copies show_form_details);
 
   $main::lxdebug->leave_sub();
 
 
 
 eval { require "lx-erp.conf"; };
 
+if (defined($latex) && !defined($latex_templates)) {
+  $latex_templates = $latex;
+  undef($latex);
+}
+
 $form = new Form;
 
 # name of this script
 
   }
 
   opendir TEMPLATEDIR, "$templates/." or $form->error("$templates : $!");
-  @all = grep !/^\.\.?$/, readdir TEMPLATEDIR;
+  my @all = readdir(TEMPLATEDIR);
+  my @alldir = sort(grep({ -d "$templates/$_" && !/^\.\.?$/ } @all));
+  my @allhtml = sort(grep({ -f "$templates/$_" && /\.html$/ } @all));
   closedir TEMPLATEDIR;
 
-  @allhtml = sort grep /\.html/, @all;
-  @alldir = grep !/\.(html|tex|sty|odt)$/, @all;
+  @alldir = grep !/\.(html|tex|sty|odt|xml|txb)$/, @alldir;
   @alldir = grep !/^(webpages|\.svn)$/, @alldir;
 
   @allhtml = reverse grep !/Default/, @allhtml;
   }
 
   opendir CSS, "css/.";
-  @all = grep /.*\.css$/, readdir CSS;
+  @all = sort(grep({ /\.css$/ && ($_ ne "tabcontent.css") } readdir(CSS)));
   closedir CSS;
 
   foreach $item (@all) {
       $selectstylesheet .= qq|<option>$item\n|;
     }
   }
-  $selectstylesheet .= "<option>\n";
 
   $form->header;
 
-  if ($myconfig->{menustyle} eq "neu") { $neu = "checked"; }
-  else { $old = "checked"; }
+  if ($myconfig->{menustyle} eq "v3") {
+    $menustyle_v3 = "checked";
+  } elsif ($myconfig->{menustyle} eq "neu") {
+    $menustyle_neu = "checked";
+  } else {
+    $menustyle_old = "checked";
+  }
 
   print qq|
 <body class=admin>
          <td><textarea name=address rows=4 cols=35>$myconfig->{address}</textarea></td>
        </tr>
         <tr valign=top>
-         <th align=right>| . $locale->text('Steuernummer') . qq|</th>
-         <td><input name=steuernummer size=14 value="$myconfig->{steuernummer}"></td>
+         <th align=right>| . $locale->text('Tax number') . qq|</th>
+         <td><input name=taxnumber size=14 value="$myconfig->{taxnumber}"></td>
        </tr>
         <tr valign=top>
          <th align=right>| . $locale->text('Ust-IDNr') . qq|</th>
        </tr>
        <tr>
            <th align=right>| . $locale->text('Setup Menu') . qq|</th>
-           <td><input name=menustyle type=radio class=radio value=neu $neu> New
-                 <input name=menustyle type=radio class=radio value=old $old> Old</td>
+           <td><input name=menustyle type=radio class=radio value=v3 $menustyle_v3> | .
+           $locale->text("Top (CSS)") . qq|
+           <input name=menustyle type=radio class=radio value=neu $menustyle_neu> | .
+           $locale->text("Top (Javascript)") . qq|
+           <input name=menustyle type=radio class=radio value=old $menustyle_old> | .
+           $locale->text("Old (on the side)") . qq|
+           </td>
          </tr>
        <input type=hidden name=templates value=$myconfig->{templates}>
       </table>
 
                <input name=category type=radio class=radio value=I $checked{I_}> |
     . $locale->text('Revenue') . qq|\n<br>
                <input name=category type=radio class=radio value=E $checked{E_}> |
-    . $locale->text('Expense') . qq|</td>
+    . $locale->text('Expense') . qq|<br>
+               <input name=category type=radio class=radio value=C $checked{C_}> |
+    . $locale->text('Costs') . qq|</td>
                <td width=50> </td>
                <td>
                <input name=charttype type=radio class=radio value="H" $checked{H}> |
 
   $form->{title} = $locale->text('Languages');
 
-  @column_index = qw(description template_code article_code);
+  @column_index = qw(description template_code article_code output_numberformat output_dateformat output_longdates);
 
   $column_header{description} =
       qq|<th class=listheading width=60%>|
       qq|<th class=listheading>|
     . $locale->text('Article Code')
     . qq|</th>|;
+  $column_header{output_numberformat} =
+      qq|<th class=listheading>|
+    . $locale->text('Number Format')
+    . qq|</th>|;
+  $column_header{output_dateformat} =
+      qq|<th class=listheading>|
+    . $locale->text('Date Format')
+    . qq|</th>|;
+  $column_header{output_longdates} =
+      qq|<th class=listheading>|
+    . $locale->text('Long Dates')
+    . qq|</th>|;
 
   $form->header;
 
     $column_data{template_code}           = qq|<td align=right>$ref->{template_code}</td>|;
     $column_data{article_code} =
       qq|<td align=right>$ref->{article_code}</td>|;
+    $column_data{output_numberformat} =
+      "<td nowrap>" .
+      ($ref->{output_numberformat} ? $ref->{output_numberformat} :
+       $locale->text("use program settings")) .
+      "</td>";
+    $column_data{output_dateformat} =
+      "<td nowrap>" .
+      ($ref->{output_dateformat} ? $ref->{output_dateformat} :
+       $locale->text("use program settings")) .
+      "</td>";
+    $column_data{output_longdates} =
+      "<td nowrap>" .
+      ($ref->{output_longdates} ? $locale->text("Yes") : $locale->text("No")) .
+      "</td>";
 
     map { print "$column_data{$_}\n" } @column_index;
 
 
   $form->header;
 
+  my $numberformat =
+    qq|<option value="">| . $locale->text("use program settings") .
+    qq|</option>|;
+  foreach $item (qw(1,000.00 1000.00 1.000,00 1000,00)) {
+    $numberformat .=
+      ($item eq $form->{output_numberformat})
+      ? "<option selected>$item"
+      : "<option>$item"
+      . "</option>";
+  }
+
+  my $dateformat =
+    qq|<option value="">| . $locale->text("use program settings") .
+    qq|</option>|;
+  foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd)) {
+    $dateformat .=
+      ($item eq $form->{output_dateformat})
+      ? "<option selected>$item"
+      : "<option>$item"
+      . "</option>";
+  }
+
   print qq|
 <body>
 
   <tr height="5"></tr>
   <tr>
     <th align=right>| . $locale->text('Language') . qq|</th>
-    <td><input name=description size=30 value="$form->{description}"></td>
+    <td><input name=description size=30 value="| . $form->quote($form->{description}) . qq|"></td>
   <tr>
   <tr>
     <th align=right>| . $locale->text('Template Code') . qq|</th>
-    <td><input name=template_code size=5 value=$form->{template_code}></td>
+    <td><input name=template_code size=5 value="| . $form->quote($form->{template_code}) . qq|"></td>
   </tr>
   <tr>
     <th align=right>| . $locale->text('Article Code') . qq|</th>
-    <td><input name=article_code size=10 value=$form->{article_code}></td>
+    <td><input name=article_code size=10 value="| . $form->quote($form->{article_code}) . qq|"></td>
+  </tr>
+  <tr>
+    <th align=right>| . $locale->text('Number Format') . qq|</th>
+    <td><select name="output_numberformat">$numberformat</select></td>
+  </tr>
+  <tr>
+    <th align=right>| . $locale->text('Date Format') . qq|</th>
+    <td><select name="output_dateformat">$dateformat</select></td>
+  </tr>
+  <tr>
+    <th align=right>| . $locale->text('Long Dates') . qq|</th>
+    <td><input type="radio" name="output_longdates" value="1"| .
+    ($form->{output_longdates} ? " checked" : "") .
+    qq|>| . $locale->text("Yes") .
+    qq|<input type="radio" name="output_longdates" value="0"| .
+    ($form->{output_longdates} ? "" : " checked") .
+    qq|>| . $locale->text("No") .
+    qq|</td>
   </tr>
   <td colspan=2><hr size=3 noshade></td>
   </tr>
     "$form->{script}?action=add_buchungsgruppe&path=$form->{path}&login=$form->{login}&password=$form->{password}"
     unless $form->{callback};
   AM->get_buchungsgruppe(\%myconfig, \%$form);
-  if ($eur) {
-    $form->{"inventory_accno_id"} = $form->{"std_inventory_accno_id"};
+  $form->{"inventory_accno_id"} = $form->{"std_inventory_accno_id"};
+  for (my $i = 0; 4 > $i; $i++) {
+    map({ $form->{"${_}_accno_id_$i"} = $form->{"std_${_}_accno_id"}; }
+        qw(income expense));
   }
 
   &buchungsgruppe_header;
 
 <input name=callback type=hidden value="$form->{callback}">
 
-<input type=hidden name=type value=business>
+<input type=hidden name=type value=payment>
 
 <input type=hidden name=path value=$form->{path}>
 <input type=hidden name=login value=$form->{login}>
     $myconfig{$item} =~ s/\\n/\r\n/g;
   }
 
+  @formats = ();
+  if ($opendocument_templates && $openofficeorg_writer_bin &&
+      $xvfb_bin && (-x $openofficeorg_writer_bin) && (-x $xvfb_bin)) {
+    push(@formats, { "name" => $locale->text("PDF (OpenDocument/OASIS)"),
+                     "value" => "opendocument_pdf" });
+  }
+  if ($latex_templates) {
+    push(@formats, { "name" => $locale->text("PDF"), "value" => "pdf" });
+  }
+  push(@formats, { "name" => "HTML", "value" => "html" });
+  if ($latex_templates) {
+    push(@formats, { "name" => $locale->text("Postscript"),
+                     "value" => "postscript" });
+  }
+  if ($opendocument_templates) {
+    push(@formats, { "name" => $locale->text("OpenDocument/OASIS"),
+                     "value" => "opendocument" });
+  }
+
+  if (!$myconfig{"template_format"}) {
+    $myconfig{"template_format"} = "pdf";
+  }
+  $template_format = "";
+  foreach $item (@formats) {
+    $template_format .=
+      "<option value=\"$item->{value}\"" .
+      ($item->{"value"} eq $myconfig{"template_format"} ?
+       " selected" : "") .
+       ">" . H($item->{"name"}) . "</option>";
+  }
+
   %countrycodes = User->country_codes;
   $countrycodes = '';
   foreach $key (sort { $countrycodes{$a} cmp $countrycodes{$b} }
 
   $form->header;
 
-  if ($myconfig{menustyle} eq "old") { $oldS = "checked"; }
-  else { $newS = "checked"; }
+  if ($myconfig{menustyle} eq "old") {
+    $menustyle_old = "checked";
+  } elsif ($myconfig{menustyle} eq "neu") {
+    $menustyle_neu = "checked";
+  } elsif ($myconfig{menustyle} eq "v3") {
+    $menustyle_v3 = "checked";
+  }
+
+  my ($show_form_details, $hide_form_details);
+  $myconfig{"show_form_details"} = 1
+    unless (defined($myconfig{"show_form_details"}));
+  $show_form_details = "checked" if ($myconfig{"show_form_details"});
+  $hide_form_details = "checked" unless ($myconfig{"show_form_details"});
 
   print qq|
 <body>
        </tr>
        <tr>
          <th align=right>| . $locale->text('Setup Menu') . qq|</th>
-         <td><input name=menustyle type=radio class=radio value=neu $newS> New
-                 <input name=menustyle type=radio class=radio value=old $oldS> Old</td>
-       </tr>   
+         <td><input name=menustyle type=radio class=radio value=v3 $menustyle_v3> | .
+    $locale->text("Top (CSS)") . qq|
+         <input name=menustyle type=radio class=radio value=neu $menustyle_neu> | .
+    $locale->text("Top (Javascript)") . qq|
+    <input name=menustyle type=radio class=radio value=old $menustyle_old> | .
+    $locale->text("Old (on the side)") . qq|</td>
+  </tr>
+  <tr>
+    <th align=right>| . $locale->text('Form details (second row)') . qq|</th>
+    <td><input type="radio" id="rad_show_form_details" name="show_form_details" value="1" $show_form_details> 
+    <label for="rad_show_form_details">| . $locale->text('Show by default') . qq|</label>
+    <input type="radio" id="rad_hide_form_details" name="show_form_details" value="0" $hide_form_details> 
+    <label for="rad_hide_form_details">| . $locale->text('Hide by default') . qq|</label></td>
+       </tr>
        <input name=printer type=hidden value="$myconfig{printer}">
+       <tr class=listheading>
+         <th colspan=2>| . $locale->text("Print options") . qq|</th>
+       </tr>
+       <tr>
+         <th align=right>| . $locale->text('Default template format') . qq|</th>
+         <td><select name="template_format">$template_format</select></td>
+       </tr>
+       <tr>
+         <th align=right>| . $locale->text('Number of copies') . qq|</th>
+         <td><input name="copies" size="10" value="| .
+    $form->quote($myconfig{"copies"}) . qq|"></td>
+       </tr>
+
+
        <tr class=listheading>
          <th colspan=2> </th>
        </tr>
          <td><input name=businessnumber size=25 value="$myconfig{businessnumber}"></td>
        </tr>
        <tr>
-         <td colspan=2>
-           <table width=100%>
-             <tr>
                <th align=right>| . $locale->text('Year End') . qq| (mm/dd)</th>
                <td><input name=yearend size=5 value=$form->{defaults}{yearend}></td>
-               <th align=right>| . $locale->text('Weight Unit') . qq|</th>
-               <td><input name=weightunit size=5 value="$form->{defaults}{weightunit}"></td>
-             </tr>
-           </table>
-         </td>
        </tr>
        <tr class=listheading>
          <th colspan=2>|
   AM->units_in_use(\%myconfig, $form, $units);
   map({ $units->{$_}->{"BASE_UNIT_DDBOX"} = AM->unit_select_data($units, $units->{$_}->{"base_unit"}, 1); } keys(%{$units}));
 
+  @languages = AM->language(\%myconfig, $form, 1);
+
   @unit_list = ();
   foreach $name (sort({ lc($a) cmp lc($b) } grep({ !$units->{$_}->{"base_unit"} } keys(%{$units})))) {
     map({ push(@unit_list, $units->{$_}); }
         sort({ ($units->{$a}->{"resolved_factor"} * 1) <=> ($units->{$b}->{"resolved_factor"} * 1) }
              grep({ $units->{$_}->{"resolved_base_unit"} eq $name } keys(%{$units}))));
   }
-  map({ $_->{"factor"} = $form->format_amount(\%myconfig, $_->{"factor"}, 5) if ($_->{"factor"}); } @unit_list);
+  my $i = 1;
+  foreach (@unit_list) {
+    $_->{"factor"} = $form->format_amount(\%myconfig, $_->{"factor"}, 5) if ($_->{"factor"});
+    $_->{"UNITLANGUAGES"} = [];
+    foreach my $lang (@languages) {
+      push(@{ $_->{"UNITLANGUAGES"} },
+           { "idx" => $i,
+             "unit" => $_->{"name"},
+             "language_id" => $lang->{"id"},
+             "localized" => $_->{"LANGUAGES"}->{$lang->{"template_code"}}->{"localized"},
+             "localized_plural" => $_->{"LANGUAGES"}->{$lang->{"template_code"}}->{"localized_plural"},
+           });
+    }
+    $i++;
+  }
 
   $units = AM->retrieve_units(\%myconfig, $form, $form->{"unit_type"});
   $ddbox = AM->unit_select_data($units, undef, 1);
 
   $form->{"title"} = sprintf($locale->text("Add and edit %s"), $form->{"unit_type"} eq "dimension" ? $locale->text("dimension units") : $locale->text("service units"));
   $form->header();
-  print($form->parse_html_template("am/edit_units", { "UNITS" => \@unit_list, "NEW_BASE_UNIT_DDBOX" => $ddbox }));
+  print($form->parse_html_template("am/edit_units",
+                                   { "UNITS" => \@unit_list,
+                                     "NEW_BASE_UNIT_DDBOX" => $ddbox,
+                                     "LANGUAGES" => \@languages }));
 
   $lxdebug->leave_sub();
 }
 
   $form->isblank("new_name", $locale->text("The name is missing."));
   $units = AM->retrieve_units(\%myconfig, $form, $form->{"unit_type"});
-  $form->show_generic_error($locale->text("A unit with this name does already exist.")) if ($units->{$form->{"new_name"}});
+  $all_units = AM->retrieve_units(\%myconfig, $form);
+  $form->show_generic_error($locale->text("A unit with this name does already exist.")) if ($all_units->{$form->{"new_name"}});
 
   my ($base_unit, $factor);
   if ($form->{"new_base_unit"}) {
     $base_unit = $form->{"new_base_unit"};
   }
 
-  AM->add_unit(\%myconfig, $form, $form->{"new_name"}, $base_unit, $factor, $form->{"unit_type"});
+  my @languages;
+  foreach my $lang (AM->language(\%myconfig, $form, 1)) {
+    next unless ($form->{"new_localized_$lang->{id}"} || $form->{"new_localized_plural_$lang->{id}"});
+    push(@languages, { "id" => $lang->{"id"},
+                       "localized" => $form->{"new_localized_$lang->{id}"},
+                       "localized_plural" => $form->{"new_localized_plural_$lang->{id}"},
+         });
+  }
+
+  AM->add_unit(\%myconfig, $form, $form->{"new_name"}, $base_unit, $factor, $form->{"unit_type"}, \@languages);
 
   $form->{"saved_message"} = $locale->text("The unit has been saved.");
 
   $lxdebug->leave_sub();
 }
 
+sub set_unit_languages {
+  $lxdebug->enter_sub();
+
+  my ($unit, $languages, $idx) = @_;
+
+  $unit->{"LANGUAGES"} = [];
+
+  foreach my $lang (@{$languages}) {
+    push(@{ $unit->{"LANGUAGES"} },
+         { "id" => $lang->{"id"},
+           "localized" => $form->{"localized_${idx}_$lang->{id}"},
+           "localized_plural" => $form->{"localized_plural_${idx}_$lang->{id}"},
+         });
+  }
+
+  $lxdebug->leave_sub();
+}
+
 sub save_unit {
   $lxdebug->enter_sub();
 
   $old_units = AM->retrieve_units(\%myconfig, $form, $form->{"unit_type"}, "resolved_");
   AM->units_in_use(\%myconfig, $form, $old_units);
 
+  @languages = AM->language(\%myconfig, $form, 1);
+
   $new_units = {};
   @delete_units = ();
   foreach $i (1..($form->{"rowcount"} * 1)) {
     if ($form->{"unchangeable_$i"}) {
       $new_units->{$form->{"old_name_$i"}} = $old_units->{$form->{"old_name_$i"}};
       $new_units->{$form->{"old_name_$i"}}->{"unchanged_unit"} = 1;
+      set_unit_languages($new_units->{$form->{"old_name_$i"}}, \@languages, $i);
       next;
     }
 
     my %h = map({ $_ => $form->{"${_}_$i"} } qw(name base_unit factor old_name));
     $new_units->{$form->{"name_$i"}} = \%h;
     $new_units->{$form->{"name_$i"}}->{"row"} = $i;
+    set_unit_languages($new_units->{$form->{"old_name_$i"}}, \@languages, $i);
   }
 
   foreach $unit (values(%{$new_units})) {
 
     unless $form->{callback};
 
   &create_links;
+  AP->get_transdate(\%myconfig, $form);
   &display_form;
 
   $lxdebug->leave_sub();
           }
           $form->{"${key}_$k"} =
             "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+          my $q_description = quotemeta($form->{acc_trans}{$key}->[$i-1]->{description});
           $form->{"select${key}"} =~
-            /<option value=\"($form->{acc_trans}{$key}->[$i-1]->{accno}--[^\"]*)\">$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}<\/option>\n/;
-          $test = $1;
+            /<option value=\"($form->{acc_trans}{$key}->[$i-1]->{accno}--[^\"]*)\">$form->{acc_trans}{$key}->[$i-1]->{accno}--${q_description}<\/option>\n/;
           $form->{"${key}_$k"} = $1;
           if ($akey eq 'amount') {
             $form->{"taxchart_$k"} = $form->{taxchart};
         </tr>
 ";
 
+  my @triggers = ();
   $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
   for $i (1 .. $form->{paidaccounts}) {
     print "
       qq|<td align=center><select name="AP_paid_$i">$form->{"selectAP_paid_$i"}</select></td>|;
     $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|;
     $column_data{"datepaid_$i"}     =
-      qq|<td align=center><input name="datepaid_$i" size=11 title="($myconfig{'dateformat'})" value=$form->{"datepaid_$i"}></td>|;
+      qq|<td align=center><input name="datepaid_$i" size=11 title="($myconfig{'dateformat'})" value=$form->{"datepaid_$i"}>
+         <input type="button" name="datepaid_$i" id="trigger_datepaid_$i" value="?"></td>|;
     $column_data{"source_$i"} =
       qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|;
     $column_data{"memo_$i"} =
     print "
         </tr>
 ";
+    push(@triggers, "datepaid_$i", "BL", "trigger_datepaid_$i");
   }
   map { $form->{$_} =~ s/\"/"/g } qw(selectAP_paid);
-  print qq|
+  print $form->write_trigger(\%myconfig, scalar(@triggers) / 3, @triggers) .
+    qq|
     <input type=hidden name=paidaccounts value=$form->{paidaccounts}>
     <input type=hidden name=selectAP_paid value="$form->{selectAP_paid}">
 
   $transdate = $form->datetonum($form->{transdate}, \%myconfig);
   $closedto  = $form->datetonum($form->{closedto},  \%myconfig);
 
-  if ($form->{id} && $form->{radier}) {
+  if ($form->{id}) {
 
     #     print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
     # |;
+  if ($form->{radier}) {
         print qq|
        <input class=submit type=submit name=action value="|
           . $locale->text('Post') . qq|">
        <input class=submit type=submit name=action value="|
           . $locale->text('Delete') . qq|">
 |;
+  }
 
-
-    if ($transdate > $closedto) {
       print qq|
 <input class=submit type=submit name=action value="|
-        . $locale->text('Post as new') . qq|">
+        . $locale->text('Use As Template') . qq|">
 |;
-    }
-
+ 
   } else {
     if (($transdate > $closedto) && !$form->{id}) {
       print qq|<input class=submit type=submit name=action value="|
   $lxdebug->leave_sub();
 }
 
+sub use_as_template {
+  $lxdebug->enter_sub();
+
+  map { delete $form->{$_} } qw(printed emailed queued invnumber invdate deliverydate id datepaid_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno);
+  $form->{paidaccounts} = 1;
+  $form->{rowcount}--;
+  $form->{invdate} = $form->current_date(\%myconfig);
+  &update;
+
+  $lxdebug->leave_sub();
+}
+
 sub delete {
   $lxdebug->enter_sub();
 
 
     unless $form->{callback};
 
   &create_links;
+  AR->get_transdate(\%myconfig, $form);
   &display_form;
 
   $lxdebug->leave_sub();
   $form->{rowcount}    = 1;
 
   # currencies
-  @curr = split /:/, $form->{currencies};
+  @curr = split(/:/, $form->{currencies});
   chomp $curr[0];
   $form->{defaultcurrency} = $curr[0];
 
             "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
           $form->{"${key}_$i"} =
             "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+          my $q_description = quotemeta($form->{acc_trans}{$key}->[$i-1]->{description});
           $form->{"select${key}"} =~
-            /<option value=\"($form->{acc_trans}{$key}->[$i-1]->{accno}--[^\"]*)\">$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}<\/option>\n/;
-          $test = $1;
+            /<option value=\"($form->{acc_trans}{$key}->[$i-1]->{accno}--[^\"]*)\">$form->{acc_trans}{$key}->[$i-1]->{accno}--${q_description}<\/option>\n/;
           $form->{"${key}_$k"} = $1;
           if ($akey eq 'amount') {
             $form->{"taxchart_$k"} = $form->{taxchart};
         </tr>
 ";
 
+  my @triggers = ();
   $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
   for $i (1 .. $form->{paidaccounts}) {
     print "
       qq|<td align=center><select name="AR_paid_$i">$form->{"selectAR_paid_$i"}</select></td>|;
     $column_data{exchangerate} = qq|<td align=center>$exchangerate</td>|;
     $column_data{datepaid}     =
-      qq|<td align=center><input name="datepaid_$i" size=11 value=$form->{"datepaid_$i"}></td>|;
+      qq|<td align=center><input name="datepaid_$i" size=11 value=$form->{"datepaid_$i"}>
+         <input type="button" name="datepaid_$i" id="trigger_datepaid_$i" value="?"></td>|;
     $column_data{source} =
       qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|;
     $column_data{memo} =
     print "
         </tr>
 ";
+    push(@triggers, "datepaid_$i", "BL", "trigger_datepaid_$i");
   }
   map { $form->{$_} =~ s/\"/"/g } qw(selectAR_paid);
-  print qq|
+
+  print $form->write_trigger(\%myconfig, scalar(@triggers) / 3, @triggers) .
+    qq|
 <input type=hidden name=paidaccounts value=$form->{paidaccounts}>
 <input type=hidden name=selectAR_paid value="$form->{selectAR_paid}">
 
           <input class=submit type=submit name=action value="|
             . $locale->text('Delete') . qq|">
   |;
-  
+  }
       if ($transdate > $closedto) {
         print qq|
   <input class=submit type=submit name=action value="|
-          . $locale->text('Post as new') . qq|">
+          . $locale->text('Use As Template') . qq|">
   |;
       }
-    }
+    
   } else {
     if ($transdate > $closedto) {
       print qq|<input class=submit type=submit name=action value="|
   $lxdebug->leave_sub();
 }
 
+sub use_as_template {
+  $lxdebug->enter_sub();
+
+  map { delete $form->{$_} } qw(printed emailed queued invnumber invdate deliverydate id datepaid_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno);
+  $form->{paidaccounts} = 1;
+  $form->{rowcount}--;
+  $form->{invdate} = $form->current_date(\%myconfig);
+  &update;
+
+  $lxdebug->leave_sub();
+}
+
 sub delete {
   $lxdebug->enter_sub();
 
   }
 
   @columns = $form->sort_columns(
-    qw(transdate id invnumber ordnumber name netamount tax amount paid datepaid due duedate notes employee shippingpoint shipvia)
+    qw(transdate id type invnumber ordnumber name netamount tax amount paid datepaid due duedate notes employee shippingpoint shipvia)
   );
 
+  $form->{"l_type"} = "Y";
+
   foreach $item (@columns) {
     if ($form->{"l_$item"} eq "Y") {
       push @column_index, $item;
       "<th><a class=listheading href=$href&sort=duedate>"
     . $locale->text('Due Date')
     . "</a></th>";
+  $column_header{type} =
+      "<th class=\"listheading\">" . $locale->text('Type') . "</th>";
   $column_header{invnumber} =
       "<th><a class=listheading href=$href&sort=invnumber>"
     . $locale->text('Invoice')
 
     $column_data{invnumber} =
       "<td><a href=$module?action=edit&id=$ar->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ar->{invnumber}</a></td>";
+    $column_data{type} = "<td>" .
+      ($ar->{storno} ? $locale->text("Storno (one letter abbreviation)") :
+       $ar->{amount} < 0 ?
+       $locale->text("Credit note (one letter abbreviation)") :
+       $locale->text("Invoice (one letter abbreviation)")) . "</td>";
     $column_data{ordnumber} = "<td>$ar->{ordnumber} </td>";
     $column_data{name}      = "<td>$ar->{name}</td>";
     $ar->{notes} =~ s/\r\n/<br>/g;
 
     # construct link to source
     $href =
       "<a href=$ca->{module}.pl?path=$form->{path}&action=edit&id=$ca->{id}&login=$form->{login}&password=$form->{password}&callback=$callback>$ca->{reference}</a>";
-
+    my $debit = ($ca->{debit} != 0) ? $form->format_amount(\%myconfig, $ca->{debit}, 2, " ") : " ";
     $column_data{debit} =
-      "<td align=right>"
-      . $form->format_amount(\%myconfig, $ca->{debit}, 2, " ") . "</td>";
+      "<td align=right>$debit</td>";
+    my $credit = ($ca->{credit} != 0) ? $form->format_amount(\%myconfig, $ca->{credit}, 2, " ") : " ";
     $column_data{credit} =
-      "<td align=right>"
-      . $form->format_amount(\%myconfig, $ca->{credit}, 2, " ") . "</td>";
+      "<td align=right>$credit</td>";
 
     $form->{balance} += $ca->{amount};
     $column_data{balance} =
 
   return $form->quote_html($_[0]);
 }
 
+sub format_dates {
+  $lxdebug->enter_sub();
+
+  my ($dateformat, $longformat, @indices) = @_;
+
+  $dateformat = $myconfig{"dateformat"} unless ($dateformat);
+
+  foreach my $idx (@indices) {
+    next unless (defined($form->{$idx}));
+
+    if (!ref($form->{$idx})) {
+      $form->{$idx} = $locale->reformat_date(\%myconfig, $form->{$idx},
+                                             $dateformat, $longformat);
+
+    } elsif (ref($form->{$idx}) eq "ARRAY") {
+      for (my $i = 0; $i < scalar(@{$form->{$idx}}); $i++) {
+        $form->{$idx}->[$i] =
+          $locale->reformat_date(\%myconfig, $form->{$idx}->[$i],
+                                 $dateformat, $longformat);
+      }
+    }
+  }
+
+  $lxdebug->leave_sub();
+}
+
+sub reformat_numbers {
+  $lxdebug->enter_sub();
+
+  my ($numberformat, $places, @indices) = @_;
+
+  return $lxdebug->leave_sub()
+    if (!$numberformat || ($numberformat eq $myconfig{"numberformat"}));
+
+  foreach my $idx (@indices) {
+    next unless (defined($form->{$idx}));
+
+    if (!ref($form->{$idx})) {
+      $form->{$idx} = $form->parse_amount(\%myconfig, $form->{$idx});
+
+    } elsif (ref($form->{$idx}) eq "ARRAY") {
+      for (my $i = 0; $i < scalar(@{$form->{$idx}}); $i++) {
+        $form->{$idx}->[$i] =
+          $form->parse_amount(\%myconfig, $form->{$idx}->[$i]);
+      }
+    }
+  }
+
+  my $saved_numberformat = $myconfig{"numberformat"};
+  $myconfig{"numberformat"} = $numberformat;
+
+  foreach my $idx (@indices) {
+    next unless (defined($form->{$idx}));
+
+    if (!ref($form->{$idx})) {
+      $form->{$idx} = $form->format_amount(\%myconfig, $form->{$idx}, $places);
+
+    } elsif (ref($form->{$idx}) eq "ARRAY") {
+      for (my $i = 0; $i < scalar(@{$form->{$idx}}); $i++) {
+        $form->{$idx}->[$i] =
+          $form->format_amount(\%myconfig, $form->{$idx}->[$i], $places);
+      }
+    }
+  }
+
+  $myconfig{"numberformat"} = $saved_numberformat;
+
+  $lxdebug->leave_sub();
+}
+
 1;
 
 
   my $pjy = new CGI::Ajax( 'get_shipto' => $get_shipto_url );
   $form->{selectshipto} = "<option value=0></option>";
+  $form->{selectshipto} .= "<option value=0>Alle</option>";
   if (@{ $form->{SHIPTO} }) {
     foreach $item (@{ $form->{SHIPTO} }) {
       if ($item->{shipto_id} == $form->{shipto_id}) {
   # $locale->text('Customer Number')
   # $locale->text('Vendor Number')
   $form->{fokus} = "ct.greeting";
+  $form->{jsscript} = 1;
   $form->header;
 
   print qq|
        <tr>
          <th align=right>| . $locale->text('Credit Limit') . qq|</th>
          <td><input name=creditlimit size=9 value="$form->{creditlimit}"></td>
-         <th align=right>| . $locale->text('Terms: Net') . qq|</th>
-         <td><input name=terms size=2 value="$form->{terms}">|
-    . $locale->text('days') . qq|</td>
+         <input type="hidden" name="terms" value="$form->{terms}">
+         <th align=right>| . $locale->text('Payment Terms') . qq|</th>
+         <td><select name=payment_id>$payment</select></td>
          <th align=right>| . $locale->text('Discount') . qq|</th>
          <td><input name=discount size=4 value="$form->{discount}">
          %</td>
          <th align=right>| . $locale->text('Tax Number / SSN') . qq|</th>
          <td><input name=taxnumber size=20 value="$form->{taxnumber}"></td>
           <th align=right>| . $locale->text('USt-IdNr.') . qq|</th>
-         <td><input name=ustid size=20 value="$form->{ustid}"></td>
+         <td><input name="ustid" maxlength="14" size="20" value="$form->{ustid}"></td>
           $customer
        </tr>
         <tr>
         <tr>
           <td align=right>| . $locale->text('Obsolete') . qq|</td>
           <td><input name=obsolete class=checkbox type=checkbox value=1 $form->{obsolete}></td>
-         <th align=right>| . $locale->text('Payment Terms') . qq|</th>
-         <td><select name=payment_id>$payment
-                          </select></td>
        </tr>
         $taxzone
       </table>
     $delivery
     <tr>
       <th align=left nowrap>| . $locale->text('From') . qq|</th>
-      <td><input id=from name=from size=10 maxlength=10 value="$form->{from}"></td>
-      <th align=left nowrap>| . $locale->text('Bis') . qq|</th>
-      <td><input id=to name=to size=10 maxlength=10 value="$form->{to}"></td>
+      <td><input id=from name=from size=10 maxlength=10 value="$form->{from}">
+        <input type="button" name="from" id="trigger_from" value="?"></td>
+      <th align=left nowrap>| . $locale->text('To (time)') . qq|</th>
+      <td><input id=to name=to size=10 maxlength=10 value="$form->{to}">
+        <input type="button" name="to" id="trigger_to" value="?"></td>
     </tr>       
     <tr>
      <td colspan=4>
 
 </div>
 
-|;
+| . $form->write_trigger(\%myconfig, 2, "from", "BL", "trigger_from",
+                         "to", "BL", "trigger_to");
 
   $lxdebug->leave_sub();
 }
 
 #
 #======================================================================
 
+use POSIX qw(strftime getcwd);
+use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
+
+use SL::Common;
 use SL::DATEV;
 
 1;
          <td><input name=datentraegernr size=5 maxlength=3 value="$form->{datentraegernr}"></td>
        </tr>
        <tr>
-         <td><input checked name=kne type=checkbox class=checkbox value=1> |
-    . $locale->text("Kontonummernerweiterung (KNE)") . qq|</td>
+         | . # OBE-Export noch nicht implementiert! <td><input checked name=kne type=checkbox class=checkbox value=1> | . $locale->text("Kontonummernerweiterung (KNE)") . qq|</td>
+    qq|<td><input type="hidden" name="kne" value="1"></td>
           <td></td>
 
          <td align=left nowrap>| . $locale->text("Abrechnungsnummer") . qq|</td>
          <td><input name=abrechnungsnr size=5 maxlength=3 value="$form->{abrechnungsnr}"></td>
        </tr>
+
         <tr>
           <td><input name=exporttype type=radio class=radio value=0 checked> |
     . $locale->text("Export Buchungsdaten") . qq|</td>
     . $locale->text('III') . qq|</option>
                          <option value=4>|
     . $locale->text('IV') . qq|</option>|;
+  $form->{"jsscript"} = 1;
   $form->header;
 
   print qq|
         <tr>
           <td align=left><input name=zeitraum class=radio type=radio value=zeit> </td><td align=left>|
     . $locale->text('Datum von') . qq|</td>
-          <td align=left><input name=transdatefrom size=8></td>
+          <td align=left><input id=transdatefrom name=transdatefrom size=10>
+            <input type="button" name="transdatefrom" id="trigger_transdatefrom" value="?"></td>
          <td align=left>| . $locale->text('bis') . qq|</td>
-          <td align=left><input name=transdateto size=8></td>
+          <td align=left><input id=transdateto name=transdateto size=10>
+            <input type="button" name="transdateto" id="trigger_transdateto" value="?"></td>
        </tr>
       </table>
     </td>
   </tr>
 </table>
 
+| . $form->write_trigger(\%myconfig, 2,
+                         "transdatefrom", "BL", "trigger_transdatefrom",
+                         "transdateto", "BL", "trigger_transdateto") . qq|
+
 <input type=hidden name=beraternr value="$form->{beraternr}">
 <input type=hidden name=dfvkz value="$form->{dfvkz}">
 <input type=hidden name=beratername value="$form->{beratername}">
 
   DATEV->save_datev_stamm(\%myconfig, \%$form);
 
+  my $link = $form->{"script"} . "?";
+  map({ $link .= "${_}=" . $form->escape($form->{$_}) . "&"; } qw(path login password));
+  $link .= "action=download";
+
   if ($form->{kne}) {
-    if (DATEV->kne_export(\%myconfig, \%$form)) {
-      $form->redirect($locale->text('KNE Export erfolgreich!'));
+    my @filenames = DATEV->kne_export(\%myconfig, \%$form);
+    if (@filenames) {
+      print(qq|<br><b>| . $locale->text('KNE-Export erfolgreich!') . qq|</b><br>|);
+      $link .= "&filenames=" . $form->escape(join(":", @filenames));
+      print(qq|<br><a href="$link">Download</a>|);
+    } else {
+      $form->error("KNE-Export schlug fehl.");
     }
   } else {
-    if (DATEV->obe_export(\%myconfig, \%$form)) {
-      $form->redirect($locale->text('OBE Export erfolgreich!'));
+    my @filenames = DATEV->obe_export(\%myconfig, \%$form);
+    if (@filenames) {
+      print(qq|<br><b>| . $locale->text('OBE-Export erfolgreich!') . qq|</b><br>|);
+      $link .= "&filenames=" . $form->escape(join(":", @filenames));
+      print(qq|<br><a href="$link">Download</a>|);
+    } else {
+      $form->error("OBE-Export schlug fehl.");
     }
   }
+
+  print("</body></html>");
+
+  $lxdebug->leave_sub();
+}
+
+sub download {
+  $lxdebug->enter_sub();
+
+  my $tmp_name = Common->tmpname();
+  my $zip_name = strftime("lx-office-datev-export-%Y%m%d.zip",
+                          localtime(time()));
+
+  my $cwd = getcwd();
+  chdir("users") || die("chdir users");
+
+  my @filenames = split(/:/, $form->{"filenames"});
+  map({ s|.*/||; $form->error("Eine der KNE-Exportdateien wurde nicht " .
+                              "gefunden. Wurde der Export bereits " .
+                              "durchgeführt?") unless (-f $_); }
+      @filenames);
+
+  my $zip = Archive::Zip->new();
+  map({ $zip->addFile($_); } @filenames);
+  $zip->writeToFileNamed($tmp_name);
+  chdir($cwd);
+
+  open(IN, $tmp_name) || die("open $tmp_name");
+  print("Content-Type: application/zip\n");
+  print("Content-Disposition: attachment; filename=\"${zip_name}\"\n\n");
+  while (<IN>) {
+    print($_);
+  }
+  close(IN);
+
+  unlink($tmp_name);
+
   $lxdebug->leave_sub();
 }
 
         $form->{totalcredit} += $ref->{amount};
         $form->{"credit_$i"} = $ref->{amount};
       }
-      $form->{"taxchart_$i"} = "0--";
+      $form->{"taxchart_$i"} = "0--0.00";
       $i++;
     }
     if ($ref->{taxaccno} && !$tax) {
        <tr>
          <th align=right>| . $locale->text('From') . qq|</th>
           $button1
+         <th align=right>| . $locale->text('To (time)') . qq|</th>
           $button2
        </tr>
        <tr>
         : $form->{"debit_$i"};
       $j = $#a;
       if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
-        $form->{"taxchart_$i"} = "0--";
+        $form->{"taxchart_$i"} = "0--0.00";
         $form->{"tax_$i"}      = 0;
       }
       if (!$form->{"korrektur_$i"}) {
         : $form->{"debit_$i"};
       $j = $#a;
       if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
-        $form->{"taxchart_$i"} = "0--";
+        $form->{"taxchart_$i"} = "0--0.00";
         $form->{"tax_$i"}      = 0;
       }
       if (!$form->{"korrektur_$i"}) {
 
                <td width=5%> </td>
                <th>| . $locale->text('From') . qq|</th>
                 $button1
-               <th>| . $locale->text('To') . qq|</th>
+               <th>| . $locale->text('To (time)') . qq|</th>
                 $button2
              </tr>
            </table>
                    <tr>
                      <th>| . $locale->text('From') . qq|</th>
                      $button1
-                     <th>| . $locale->text('To') . qq|</th>
+                     <th>| . $locale->text('To (time)') . qq|</th>
                      $button2
                    </tr>
                  </table>
     if ($form->{transdateto}) {
       $callback .= "&transdateto=$form->{transdateto}";
       $option   .= "\n<br>"
-        . $locale->text('To')
+        . $locale->text('To (time)')
         . " "
         . $locale->date(\%myconfig, $form->{transdateto}, 1);
     }
 
   IC->get_part(\%myconfig, \%$form);
 
+  $form->{"original_partnumber"} = $form->{"partnumber"};
+
   $form->{title} = $locale->text('Edit ' . ucfirst $form->{item});
 
   &link_part;
                      <td>
                        <input name=weight size=10 value=$form->{weight}>
                      </td>
-                     <th>
-                        
-                       $form->{weightunit}
-                       <input type=hidden name=weightunit value=$form->{weightunit}>
-                     </th>
                    </tr>
                  </table>
                </td>
                         $form->{weight}
                        <input type=hidden name=weight value=$form->{weight}>
                      </td>
-                     <th>
-                        
-                       $form->{weightunit}
-                       <input type=hidden name=weightunit value=$form->{weightunit}>
-                     </th>
                    </tr>
                  </table>
                </td>
 <input name=rowcount type=hidden value=$form->{rowcount}>
 <input name=eur type=hidden value=$eur>
 <input name=language_values type=hidden value="$form->{language_values}">
+<input name="original_partnumber" type="hidden" value="| . $form->quote($form->{"original_partnumber"}) . qq|">
 
 <table width="100%">
   <tr>
   $lxdebug->enter_sub();
 
   $form->{id} = 0;
-  $form->{partnumber} = "";
+  if ($form->{"original_partnumber"} &&
+      ($form->{"partnumber"} eq $form->{"original_partnumber"})) {
+    $form->{partnumber} = "";
+  }
   &save;
 
   $lxdebug->leave_sub();
 
 #
 #######################################################################
 
+use SL::CT;
 use SL::IC;
+use CGI::Ajax;
+use CGI;
+
+require "$form->{path}/common.pl";
 
 # any custom scripts for this one
 if (-f "$form->{path}/custom_io.pl") {
 sub display_row {
   $lxdebug->enter_sub();
   my $numrows = shift;
+
   if ($lizenzen && $form->{vc} eq "customer") {
     if ($form->{type} =~ /sales_order/) {
       @column_index = (runningnumber, partnumber, description, ship, qty);
     . qq|</th>|;
 ############## ENDE Neueintrag ##################
 
+  $myconfig{"show_form_details"} = 1
+    unless (defined($myconfig{"show_form_details"}));
+  $form->{"show_details"} = $myconfig{"show_form_details"}
+    unless (defined($form->{"show_details"}));
+  $form->{"show_details"} = $form->{"show_details"} ? 1 : 0;
+  my $show_details_new = 1 - $form->{"show_details"};
+  my $show_details_checked = $form->{"show_details"} ? "checked" : "";
+
   print qq|
   <tr>
     <td>
+      <input type="hidden" name="show_details" value="$form->{show_details}">
+      <input type="checkbox" id="cb_show_details" onclick="show_form_details($show_details_new);" $show_details_checked>
+      <label for="cb_show_details">| . $locale->text("Show details") . qq|</label><br>
       <table width=100%>
        <tr class=listheading>|;
 
     # Eintrag fuer Version 2.2.0 geaendert #
     # neue Optik im Rechnungsformular      #
 ########################################
+
+    my $row_style_attr =
+      'style="display:none;"' if (!$form->{"show_details"});
+
     # print second row
     print qq|
-        <tr  class=listrow$j>
+        <tr  class=listrow$j $row_style_attr>
          <td colspan=$colspan>
 |;
     if ($lizenzen && $form->{type} eq "invoice" && $form->{vc} eq "customer") {
 
 sub select_item {
   $lxdebug->enter_sub();
-  @column_index = qw(ndx partnumber description onhand sellprice);
+  @column_index = qw(ndx partnumber description onhand unit sellprice);
 
   $column_data{ndx}        = qq|<th> </th>|;
   $column_data{partnumber} =
     qq|<th class=listheading>| . $locale->text('Price') . qq|</th>|;
   $column_data{onhand} =
     qq|<th class=listheading>| . $locale->text('Qty') . qq|</th>|;
-
+  $column_data{unit} =
+    qq|<th class=listheading>| . $locale->text('Unit') . qq|</th>|;
   # list items with radio button on a form
   $form->header;
 
       qq|<td align=right><input name="new_onhand_$i" type=hidden value=$ref->{onhand}>|
       . $form->format_amount(\%myconfig, $ref->{onhand}, '', " ")
       . qq|</td>|;
-
+    $column_data{unit} =
+      qq|<td>$ref->{unit}</td>|;
     $j++;
     $j %= 2;
     print qq|
                     \%myconfig, $form->{currency}, $form->{transdate}, $buysell
                     )));
 
+  for $i (1 .. $form->{rowcount}) {
+    map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig,
+                                                     $form->{"${_}_${i}"})
+            if ($form->{"${_}_${i}"}) }
+        qw(ship qty sellprice listprice basefactor));
+  }
+
   &prepare_order;
   &display_form;
 
                     \%myconfig, $form->{currency}, $form->{transdate}, $buysell
                     )));
 
+  for $i (1 .. $form->{rowcount}) {
+    map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig,
+                                                     $form->{"${_}_${i}"})
+            if ($form->{"${_}_${i}"}) }
+        qw(ship qty sellprice listprice basefactor));
+  }
+
   &prepare_order;
   &display_form;
 
     $form->{email} = $form->{shiptoemail} if $form->{shiptoemail};
   }
 
+  if ($form->{"cp_id"} && !$form->{"email"}) {
+    CT->get_contact(\%myconfig, $form);
+    $form->{"email"} = $form->{"cp_email"};
+  }
+
   $name = $form->{ $form->{vc} };
   $name =~ s/--.*//g;
   $title = $locale->text('E-mail') . " $name";
 sub print_options {
   $lxdebug->enter_sub();
   $form->{sendmode} = "attachment";
-  $form->{copies}   = 3 unless $form->{copies};
+
+  $form->{"format"} =
+    $form->{"format"} ? $form->{"format"} :
+    $myconfig{"template_format"} ? $myconfig{"template_format"} :
+    "pdf";
+
+  $form->{"copies"} =
+    $form->{"copies"} ? $form->{"copies"} :
+    $myconfig{"copies"} ? $myconfig{"copies"} :
+    3;
 
   $form->{PD}{ $form->{formname} } = "selected";
   $form->{DF}{ $form->{format} }   = "selected";
 
   $format .= qq|<option value=html $form->{DF}{html}>HTML</option>|;
 
-  if ($latex) {
+  if ($latex_templates) {
     $format .= qq|<option value=postscript $form->{DF}{postscript}>| .
       $locale->text('Postscript') . qq|</option>|;
   }
   $form->{"cc"}    = $saved_cc    if ($saved_cc);
   $form->{"bcc"}   = $saved_bcc   if ($saved_bcc);
 
-  # format payment dates
-  for $i (1 .. $form->{paidaccounts} - 1) {
-    $form->{"datepaid_$i"} = $locale->date(\%myconfig, $form->{"datepaid_$i"});
+  my ($language_tc, $output_numberformat, $output_dateformat, $output_longdates);
+  if ($form->{"language_id"}) {
+    ($language_tc, $output_numberformat, $output_dateformat, $output_longdates) =
+      AM->get_language_details(\%myconfig, $form, $form->{language_id});
+  } else {
+    $output_dateformat = $myconfig{"dateformat"};
+    $output_numberformat = $myconfig{"numberformat"};
+    $output_longdates = 1;
   }
 
   ($form->{employee}) = split /--/, $form->{employee};
     IS->invoice_details(\%myconfig, \%$form, $locale);
   }
 
-  # format global dates
-  map { $form->{$_} = $locale->date(\%myconfig, $form->{$_}, 1) }
-    ("${inv}date", "${due}date", "shippingdate", "deliverydate");
-
-  # format item dates
-  for my $field (qw(transdate_oe deliverydate_oe)) {
-    map {
-      $form->{$field}[$_] = $locale->date(\%myconfig, $form->{$field}[$_], 1);
-    } 0 .. $#{ $form->{$field} };
-  }
-
   if ($form->{shipto_id}) {
     $form->get_shipto(\%myconfig);
   }
         || $form->{formname} eq 'request_quotation') {
       $form->{shiptoname}   = $myconfig{company};
       $form->{shiptostreet} = $myconfig{address};
-        } else {
+    } else {
       map { $form->{"shipto$_"} = $form->{$_} } @a;
     }
   }
 
   $form->{notes} =~ s/^\s+//g;
 
-  map({ $form->{$_} =~ s/\\n/\n/g; } qw(company address));
-
   $form->{templates} = "$myconfig{templates}";
 
   $form->{language} = $form->get_template_language(\%myconfig);
   $form->{printer_code} = $form->get_printer_code(\%myconfig);
 
   if ($form->{language} ne "") {
+    map({ $form->{"unit"}->[$_] =
+            AM->translate_units($form, $form->{"language"},
+                                $form->{"unit"}->[$_], $form->{"qty"}->[$_]); }
+        (0..scalar(@{$form->{"unit"}}) - 1));
     $form->{language} = "_" . $form->{language};
   }
 
+  # Format dates.
+  format_dates($output_dateformat, $output_longdates,
+               qw(invdate orddate quodate pldate duedate reqdate transdate
+                  shippingdate deliverydate validitydate paymentdate
+                  datepaid transdate_oe deliverydate_oe
+                  employee_startdate employee_enddate
+                  ),
+               grep({ /^datepaid_\d+$/ ||
+                        /^transdate_oe_\d+$/ ||
+                        /^deliverydate_oe_\d+$/ ||
+                        /^reqdate_\d+$/ ||
+                        /^deliverydate_\d+$/ ||
+                        /^transdate_\d+$/
+                    } keys(%{$form})));
+
+  reformat_numbers($output_numberformat, 2,
+                   qw(invtotal ordtotal quototal subtotal linetotal
+                      listprice sellprice netprice discount
+                      tax taxbase),
+                   grep({ /^linetotal_\d+$/ ||
+                            /^listprice_\d+$/ ||
+                            /^sellprice_\d+$/ ||
+                            /^netprice_\d+$/ ||
+                            /^taxbase_\d+$/ ||
+                            /^discount_\d+$/ ||
+                            /^tax_\d+$/
+                        } keys(%{$form})));
+
+  reformat_numbers($output_numberformat, undef,
+                   qw(qty),
+                   grep({ /^qty_\d+$/
+                        } keys(%{$form})));
+
   if ($form->{printer_code} ne "") {
     $form->{printer_code} = "_" . $form->{printer_code};
   }
 
 sub customer_details {
   $lxdebug->enter_sub();
-  IS->customer_details(\%myconfig, \%$form);
+  IS->customer_details(\%myconfig, \%$form, @_);
   $lxdebug->leave_sub();
 }
 
 sub vendor_details {
   $lxdebug->enter_sub();
 
-  IR->vendor_details(\%myconfig, \%$form);
+  IR->vendor_details(\%myconfig, \%$form, @_);
 
   $lxdebug->leave_sub();
 }
   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
     qw(exchangerate creditlimit creditremaining);
 
+  my @shipto_vars =
+    qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry
+       shiptocontact shiptophone shiptofax shiptoemail
+       shiptodepartment_1 shiptodepartment_2);
+
   # get details for name
-  &{"$form->{vc}_details"};
+  &{"$form->{vc}_details"}(@shipto_vars);
 
   $number =
     ($form->{vc} eq 'customer')
 |;
 
   # delete shipto
-  map { delete $form->{$_} }
-    qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry shiptocontact shiptophone shiptofax shiptoemail shiptodepartment_1 shiptodepartment_2 header);
+  map({ delete $form->{$_} } (@shipto_vars, qw(header)));
   $form->{title} = $title;
 
   foreach $key (keys %$form) {
 
   $lxdebug->leave_sub();
 }
+
+
+sub set_duedate {
+  $lxdebug->enter_sub();
+
+  $form->get_duedate(\%myconfig);
+
+  my $q = new CGI;
+  $result = "$form->{duedate}";
+  print $q->header();
+  print $result;
+  $lxdebug->leave_sub();
+
+}
+
 
     foreach $item (@{ $form->{TAXZONE} }) {
       if ($item->{id} == $form->{taxzone_id}) {
         $form->{selecttaxzone} .=
-          "<option value=$item->{id} selected>$item->{description}</option>";
+          "<option value=$item->{id} selected>" . H($item->{description}) .
+          "</option>";
       } else {
         $form->{selecttaxzone} .=
-          "<option value=$item->{id}>$item->{description}</option>";
+          "<option value=$item->{id}>" . H($item->{description}) . "</option>";
       }
 
     }
       $form->{selecttaxzone} =~ s/value=$form->{taxzone_id}/value=$form->{taxzone_id} selected/;
     }
   }
-  if ($form->{rowcount} >1) {
-    $form->{selecttaxzone} =~ /<option value=\d+ selected>.*?<\/option>/;
-    $form->{selecttaxzone} = $&;
-  }
-  
 
   $taxzone = qq|
              <tr>
        </tr>
 |;
 
+  my @triggers = ();
   $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
   for $i (1 .. $form->{paidaccounts}) {
 
     $column_data{"AP_paid_$i"}      =
       qq|<td align=center><select name="AP_paid_$i">$form->{"selectAP_paid_$i"}</select></td>|;
     $column_data{"datepaid_$i"} =
-      qq|<td align=center><input name="datepaid_$i" size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}></td>|;
+      qq|<td align=center><input name="datepaid_$i" size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}>
+         <input type="button" name="datepaid_$i" id="trigger_datepaid_$i" value="?"></td>|;
     $column_data{"source_$i"} =
       qq|<td align=center><input name="source_$i" size=11 value=$form->{"source_$i"}></td>|;
     $column_data{"memo_$i"} =
     print qq|
        </tr>
 |;
+    push(@triggers, "datepaid_$i", "BL", "trigger_datepaid_$i");
   }
 
   print qq|
       . $locale->text('Delete') . qq|">
 |;
   }
+    print qq|<input class=submit type=submit name=action value="|
+      . $locale->text('Use As Template') . qq|">
+|;
   } else {
     if ($invdate > $closedto) {
       print qq|<input class=submit type=submit name=action value="|
     &menubar;
   }
 
-  print qq|
+  print $form->write_trigger(\%myconfig, scalar(@triggers) / 3, @triggers) .
+    qq|
 
 <input type=hidden name=rowcount value=$form->{rowcount}>
 
   $form->{storno} = 1;
   $form->{id} = "";
   $form->{invnumber} = "Storno zu " . $form->{invnumber};
-  $form->{rowcount}--;
 
   &post();
   $lxdebug->leave_sub();
 
 }
 
+sub use_as_template {
+  $lxdebug->enter_sub();
+
+  map { delete $form->{$_} } qw(printed emailed queued invnumber invdate deliverydate id datepaid_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno);
+  $form->{paidaccounts} = 1;
+  $form->{rowcount}--;
+  $form->{invdate} = $form->current_date(\%myconfig);
+  &display_form;
+
+  $lxdebug->leave_sub();
+}
+
 sub post_payment {
   $lxdebug->enter_sub();
   for $i (1 .. $form->{paidaccounts}) {
 
   $form->{id} = 0 if $form->{postasnew};
 
-  # get new invnumber in sequence if no invnumber is given or if posasnew was requested
-  if (!$form->{invnumber} || $form->{postasnew}) {
-    $form->{invnumber} = $form->update_defaults(\%myconfig, "invnumber");
-  }
 
   relink_accounts();
   $form->redirect(  $locale->text('Invoice')
 
   }
   &invoice_links;
   &prepare_invoice;
-  $form->{format} = "pdf";
-
   &display_form;
 
   $lxdebug->leave_sub();
     }
   }
 
+  my $set_duedate_url =
+    "$form->{script}?login=$form->{login}&path=$form->{path}&password=$form->{password}&action=set_duedate";
+
+  my $pjx = new CGI::Ajax( 'set_duedate' => $set_duedate_url );
+  push(@ { $form->{AJAX} }, $pjx);
 
   if (@{ $form->{TAXZONE} }) {
     $form->{selecttaxzone} = "";
     foreach $item (@{ $form->{TAXZONE} }) {
       if ($item->{id} == $form->{taxzone_id}) {
         $form->{selecttaxzone} .=
-          "<option value=$item->{id} selected>$item->{description}</option>";
+          "<option value=$item->{id} selected>" . H($item->{description}) .
+          "</option>";
       } else {
         $form->{selecttaxzone} .=
-          "<option value=$item->{id}>$item->{description}</option>";
+          "<option value=$item->{id}>" . H($item->{description}) . "</option>";
       }
 
     }
       $form->{selecttaxzone} =~ s/value=$form->{taxzone_id}/value=$form->{taxzone_id} selected/;
     }
   }
-  if ($form->{rowcount} >0) {
-    $form->{selecttaxzone} =~ /<option value=\d+ selected>.*?<\/option>/;
-    $form->{selecttaxzone} = $&;
-  }
-  
 
   $taxzone = qq|
              <tr>
 
     }
   } else {
+    $form->{selectshipto} = $form->unquote($form->{selectshipto});
     $form->{selectshipto} =~ s/ selected//g;
     if ($form->{shipto_id} ne "") {
       $form->{selectshipto} =~ s/value=$form->{shipto_id}/value=$form->{shipto_id} selected/;
 
   $shipto = qq|
                <th align=right>| . $locale->text('Shipping Address') . qq|</th>
-               <td><select name=shipto_id style="width:200px;">$form->{selectshipto}</select></td>
-               <input type=hidden name=selectshipto value="$form->{selectshipto}">|;
+               <td><select name=shipto_id style="width:200px;">$form->{selectshipto}</select></td>|;
+  $form->{selectshipto} = $form->quote($form->{selectshipto});
+  $shipto .= qq| <input type=hidden name=selectshipto value="$form->{selectshipto}">|;
 
 
 
     $onload = qq|alert('$credittext')|;
   }
 
+  $form->{"javascript"} .= qq|<script type="text/javascript" src="js/show_form_details.js">|;
+
   $form->header;
 
   print qq|
              <tr valign=top>
                <td>$notes</td>
                <td>$intnotes</td>
-                <td><select name=payment_id tabindex=24>$payment
+                <td><select name=payment_id onChange="set_duedate(['payment_id__' + this.value],['duedate'])">$payment
                 </select></td>
              </tr>
            </table>
         </tr>
 ";
 
+  my @triggers = ();
+
   $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
   for $i (1 .. $form->{paidaccounts}) {
 
     $column_data{"AR_paid_$i"}      =
       qq|<td align=center><select name="AR_paid_$i">$form->{"selectAR_paid_$i"}</select></td>|;
     $column_data{"datepaid_$i"} =
-      qq|<td align=center><input name="datepaid_$i"  size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}></td>|;
+      qq|<td align=center><input id="datepaid_$i" name="datepaid_$i"  size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}>
+         <input type="button" name="datepaid_$i" id="trigger_datepaid_$i" value="?"></td>|;
     $column_data{"source_$i"} =
       qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|;
     $column_data{"memo_$i"} =
     map { print qq|$column_data{"${_}_$i"}\n| } @column_index;
     print "
         </tr>\n";
+    push(@triggers, "datepaid_$i", "BL", "trigger_datepaid_$i");
   }
 
   print qq|
 
   if ($form->{id}) {
     print qq|
-    <input class=submit type=submit name=action value="|
+    <input class=submit type=submit accesskey="u" name=action id=update_button value="|
       . $locale->text('Update') . qq|">
     <input class=submit type=submit name=action value="|
       . $locale->text('Ship to') . qq|">
       . $locale->text('Storno') . qq|">| unless ($form->{storno});
     print qq|<input class=submit type=submit name=action value="|
       . $locale->text('Post Payment') . qq|">
+|;
+    print qq|<input class=submit type=submit name=action value="|
+      . $locale->text('Use As Template') . qq|">
 |;
   if ($form->{id} && !($form->{type} eq "credit_note")) {
     print qq|
 
   } else {
     if ($invdate > $closedto) {
-      print qq|<input class=submit type=submit name=action value="|
+      print qq|<input class=submit type=submit name=action id=update_button value="|
         . $locale->text('Update') . qq|">
       <input class=submit type=submit name=action value="|
         . $locale->text('Ship to') . qq|">
     &menubar;
   }
 
-  print qq|
+  print $form->write_trigger(\%myconfig, scalar(@triggers) / 3, @triggers) .
+    qq|
 
 <input type=hidden name=rowcount value=$form->{rowcount}>
 
 
 }
 
+sub use_as_template {
+  $lxdebug->enter_sub();
+
+  map { delete $form->{$_} } qw(printed emailed queued invnumber invdate deliverydate id datepaid_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno);
+  $form->{paidaccounts} = 1;
+  $form->{rowcount}--;
+  $form->{invdate} = $form->current_date(\%myconfig);
+  &display_form;
+
+  $lxdebug->leave_sub();
+}
+
 sub storno {
   $lxdebug->enter_sub();
 
   $form->{storno} = 1;
   $form->{id} = "";
   $form->{invnumber} = "Storno zu " . $form->{invnumber};
-  $form->{rowcount}--;
 
   &post();
   $lxdebug->leave_sub();
 
 
 sub form_header {
   $lxdebug->enter_sub();
+  $form->{jsscript} = 1;
   $form->header();
 
   print(
       </tr>
       <tr>
         <th align=right>| . $locale->text('Valid until') . qq|</th>
-        <td><input name=validuntil value=\"|
-      . quot($form->{"validuntil"}) . qq|\"></td>
+        <td><input id=validuntil name=validuntil value=\"|
+      . quot($form->{"validuntil"}) . qq|\">
+         <input type="button" name="validuntil" id="trigger_validuntil" value="?"></td>
       </tr>
       <tr>
         <th align=right>| . $locale->text('Quantity') . qq|</th>
     qq|
   </tr>
 
-</table>|);
+</table>| .
+    $form->write_trigger(\%myconfig, 1, "validuntil", "BL",
+                         "trigger_validuntil"));
+
   $lxdebug->leave_sub();
 }
 
 
   }
 
   # made it this far, execute the menu
-  if ($user->{menustyle} eq "neu") {
+  if ($user->{menustyle} eq "v3") {
+    $form->{callback} =
+      "menuv3.pl?login=$form->{login}&password=$form->{password}&path=$form->{path}&action=display";
+  } elsif ($user->{menustyle} eq "neu") {
     $form->{callback} =
       "menunew.pl?login=$form->{login}&password=$form->{password}&path=$form->{path}&action=display";
   } else {
 
        this.target = target;
        this.ref = null;
 }
-function go(link) {
-        top.main_window.location=link;
+function go(link,frame) {
+       tmp=eval("top."+frame);
+       tmp.location=link;
+        //top.main_window.location=link;
 }
 function writeMenus() {
        if (!isDOM && !isIE4 && !isNS4) return;
                                str += '<layer id="' + itemID + '" left="' + itemX + '" top="' + itemY + '" width="' +  w + '" height="' + h + '" visibility="inherit" ';
                                if (backCol) str += 'bgcolor="' + backCol + '" ';
                        }
-                       if (borderClass) str += 'class="' + borderClass + '" ';
+                       if (borderClass) str += 'class="' + borderClass + '" "';
                        str += 'onMouseOver="popOver(' + currMenu + ',' + currItem + ')" onMouseOut="popOut(' + currMenu + ',' + currItem + ')">';
                        str += '<table width="' + (w - 8) + '" border="0" cellspacing="0" cellpadding="' + (!isNS4 && borderClass ? 3 : 0) + '">';
-                       if (href!="#") {
-                       str +='<tr><td align="left" height="' + (h - 7) + '" onClick=\\'go("' + href + '")\\'><a class="' + textClass + '" href="' + href + '"' + (frame ? ' target="' + frame + '">' : '>') + text + '</a></td>';
-                       } else {
-                       str +='<tr><td align="left" height="' + (h - 7) + '"><a class="' + textClass + '" href="' + href + '"' + (frame ? ' target="' + frame + '">' : '>') + text + '</a></td>';
-                       }
+                       str +='<tr><td style="cursor:crosshair;" align="left" height="' + (h - 7) + '" onClick=\\'go("' + href + '","' + frame + '")\\'>' + text + '</a></td>';
                        if (target > 0) {
                                menu[target][0].parentMenu = currMenu;
                                menu[target][0].parentItem = currItem;
 
--- /dev/null
+#=====================================================================
+# LX-Office ERP
+# Copyright (C) 2004
+# Based on SQL-Ledger Version 2.1.9
+# Web http://www.lx-office.org
+#
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Christopher Browne
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#######################################################################
+#
+# thre frame layout with refractured menu
+#
+#######################################################################
+
+$menufile = "menu.ini";
+use SL::Menu;
+
+1;
+
+# end of main
+
+sub display {
+  $form->header(qq|<link rel="stylesheet" href="css/menuv3.css?id=| .
+                int(rand(100000)) . qq|" type="text/css">|);
+
+  print(qq|<body>\n|);
+
+  clock_line();
+
+  print qq|
+
+<div id="menu">
+
+| . acc_menu() . qq|
+
+</div>
+
+<div style="clear: both;"></div>
+
+<iframe id="win1" src="login.pl?login=$form->{login}&password=$form->{password}&action=company_logo&path=$form->{path}" width="100%" height="93%" name="main_window" style="position: absolute; border: 0px; z-index: 99; ">
+<p>Ihr Browser kann leider keine eingebetteten Frames anzeigen.
+</p>
+</iframe>
+</body>
+</html>
+
+|;
+
+}
+
+sub clock_line {
+
+  $login = "["
+    . $form->{login}
+    . " - <a href=\"login.pl?path="
+    . $form->{"path"}
+    . "&password="
+    . $form->{"password"}
+    . "&action=logout\" target=\"_top\">"
+    . $locale->text('Logout')
+    . "</a>] ";
+  my ($Sekunden, $Minuten,   $Stunden,   $Monatstag, $Monat,
+      $Jahr,     $Wochentag, $Jahrestag, $Sommerzeit)
+    = localtime(time);
+  my $CTIME_String = localtime(time);
+  $Monat     += 1;
+  $Jahrestag += 1;
+  $Monat     = $Monat < 10     ? $Monat     = "0" . $Monat     : $Monat;
+  $Monatstag = $Monatstag < 10 ? $Monatstag = "0" . $Monatstag : $Monatstag;
+  $Jahr += 1900;
+  my @Wochentage = ("Sonntag",    "Montag",  "Dienstag", "Mittwoch",
+                    "Donnerstag", "Freitag", "Samstag");
+  my @Monatsnamen = ("",       "Januar",    "Februar", "März",
+                     "April",  "Mai",       "Juni",    "Juli",
+                     "August", "September", "Oktober", "November",
+                     "Dezember");
+  $datum =
+      $Wochentage[$Wochentag] . ", der "
+    . $Monatstag . "."
+    . $Monat . "."
+    . $Jahr . " - ";
+
+  #$zeit="<div id='Uhr'>".$Stunden.":".$Minuten.":".$Sekunden."</div>";
+  $zeit = "<div id='Uhr'>" . $Stunden . ":" . $Minuten . "</div>";
+  print qq|
+<script type="text/javascript">
+<!--
+var clockid=new Array()
+var clockidoutside=new Array()
+var i_clock=-1
+var thistime= new Date()
+var hours= | . $Stunden . qq|;
+var minutes= | . $Minuten . qq|;
+var seconds= | . $Sekunden . qq|;
+if (eval(hours) <10) {hours="0"+hours}
+if (eval(minutes) < 10) {minutes="0"+minutes}
+if (seconds < 10) {seconds="0"+seconds}
+//var thistime = hours+":"+minutes+":"+seconds
+var thistime = hours+":"+minutes
+
+function writeclock() {
+       i_clock++
+       if (document.all \|\| document.getElementById \|\| document.layers) {
+               clockid[i_clock]="clock"+i_clock
+               document.write("<font family=arial size=2><span id='"+clockid[i_clock]+"' style='position:relative'>"+thistime+"</span></font>")
+       }
+}
+
+function clockon() {
+       thistime= new Date()
+       hours=thistime.getHours()
+       minutes=thistime.getMinutes()
+       seconds=thistime.getSeconds()
+       if (eval(hours) <10) {hours="0"+hours}
+       if (eval(minutes) < 10) {minutes="0"+minutes}
+       if (seconds < 10) {seconds="0"+seconds}
+       //thistime = hours+":"+minutes+":"+seconds
+       thistime = hours+":"+minutes
+
+       if (document.all) {
+               for (i=0;i<=clockid.length-1;i++) {
+                       var thisclock=eval(clockid[i])
+                       thisclock.innerHTML=thistime
+               }
+       }
+
+       if (document.getElementById) {
+               for (i=0;i<=clockid.length-1;i++) {
+                       document.getElementById(clockid[i]).innerHTML=thistime
+               }
+       }
+       var timer=setTimeout("clockon()",60000)
+}
+//window.onload=clockon
+//-->
+</script>
+<table border="0" width="100%" background="image/bg_titel.gif" cellpadding="0" cellspacing="0">
+       <tr>
+               <td  style="color:white; font-family:verdana,arial,sans-serif; font-size: 12px;">   [<a href="JavaScript:top.main_window.print()">drucken</a>]</td>
+               <td align="right" style="vertical-align:middle; color:white; font-family:verdana,arial,sans-serif; font-size: 12px;" nowrap>|
+    . $login . $datum . qq| <script>writeclock()</script> 
+               </td>
+       </tr>
+</table>
+|;
+}
+
+sub acc_menu {
+  $locale = Locale->new($language, "menu");
+
+  $mainlevel = $form->{level};
+  $mainlevel =~ s/$mainlevel--//g;
+  my $menu = new Menu "$menufile";
+  $menu = new Menu "custom_$menufile" if (-f "custom_$menufile");
+  $menu = new Menu "$form->{login}_$menufile"
+    if (-f "$form->{login}_$menufile");
+
+  $| = 1;
+
+  return print_menu($menu);
+}
+
+sub my_length {
+  my ($s) = @_;
+  my $len = 0;
+  my $i;
+  my $skip = 0;
+
+  for ($i = 0; $i < length($s); $i++) {
+    my $c = substr($s, $i, 1);
+    if ($skip && ($c eq ";")) {
+      $skip = 0;
+    } elsif ($skip) {
+      next;
+    } elsif ($c eq "&") {
+      $skip = 1;
+      $len++;
+    } else {
+      $len++;
+    }
+  }
+
+  return $len;
+}
+
+sub print_menu {
+  my ($menu, $parent, $depth) = @_;
+  my $html;
+
+  die if ($depth * 1 > 5);
+
+  my @menuorder;
+
+  @menuorder = $menu->access_control(\%myconfig, $parent);
+
+  $parent .= "--" if ($parent);
+
+  foreach my $item (@menuorder) {
+    substr($item, 0, length($parent)) = "";
+    next if (($item eq "") || ($item =~ /--/));
+
+    my $menu_item = $menu->{"${parent}${item}"};
+    my $menu_title = $locale->text($item);
+    my $menu_text = $menu_title;
+
+    $menu_text =~ s/ /<br>/ if ($parent && (my_length($menu_text) >= 17));
+
+    my $target = "main_window";
+    $target = $menu_item->{"target"} if ($menu_item->{"target"});
+
+    if ($menu_item->{"submenu"} || !defined($menu_item->{"module"}) ||
+        ($menu_item->{"module"} eq "menu.pl")) {
+
+      my $h = print_menu($menu, "${parent}${item}", $depth * 1 + 1);
+      if (!$parent) {
+        $html .= qq|<ul><li><h2>${menu_text}</h2><ul>${h}</ul></li></ul>|;
+      } else {
+        $html .= qq|<li><div class="x">${menu_text}</div><ul>${h}</ul></li>|;
+      }
+    } else {
+      $html .= qq|<li>|;
+      $html .= $menu->menuitem_v3(\%myconfig, $form, "${parent}$item",
+                                  { "title" => $menu_title,
+                                    "target" => $target });
+      $html .= qq|${menu_text}</a></li>|;
+    }
+  }
+
+  return $html;
+}
 
 
 sub prepare_order {
   $lxdebug->enter_sub();
-  $form->{format}   = "pdf" unless ($form->{print_and_save} && $form->{format});
   $form->{media}    = "screen";
   $form->{formname} = $form->{type} unless $form->{formname};
 
           "<option value=$item->{shipto_id} selected>$item->{shiptoname} $item->{shiptodepartment_1}</option>";
       } else {
         $form->{selectshipto} .=
-          "<option value=$item->{shipto_id}>$item->{shiptoname} $item->{shiptodepartment_1}</option>";
+          "<option value=$item->{shipto_id}>$item->{shiptoname} $item->{shiptodepartment}</option>";
       }
 
     }
   } else {
+    $form->{selectshipto} = $form->unquote($form->{selectshipto});
     $form->{selectshipto} =~ s/ selected//g;
     if ($form->{shipto_id} ne "") {
       $form->{selectshipto} =~ s/value=$form->{shipto_id}/value=$form->{shipto_id} selected/;
 
   $shipto = qq|
                <th align=right>| . $locale->text('Shipping Address') . qq|</th>
-               <td><select name=shipto_id>$form->{selectshipto}</select></td>
-               <input type=hidden name=selectshipto value="$form->{selectshipto}">|;
-
+               <td><select name=shipto_id style="width:200px;">$form->{selectshipto}</select></td>|;
+  $form->{selectshipto} = $form->quote($form->{selectshipto});
+  $shipto .= qq| <input type=hidden name=selectshipto value="$form->{selectshipto}">|;
 
 
 
   $vclabel = ucfirst $form->{vc};
   $vclabel = $locale->text($vclabel);
 
-  $terms = qq|
-                    <tr>
-                     <th align=right nowrap>| . $locale->text('Terms: Net') . qq|</th>
-                     <td nowrap><input name=terms size="3" maxlength="3" value=$form->{terms}> |
-    . $locale->text('days') . qq|</td>
-                    </tr>
-|;
+  $terms = qq|<input name=terms size="3" maxlength="3" value="| .
+    $form->quote($form->{terms}) . qq|">|;
 
   if ($form->{business}) {
     $business = qq|
     foreach $item (@{ $form->{TAXZONE} }) {
       if ($item->{id} == $form->{taxzone_id}) {
         $form->{selecttaxzone} .=
-          "<option value=$item->{id} selected>$item->{description}</option>";
+          "<option value=$item->{id} selected>" . H($item->{description}) .
+          "</option>";
       } else {
         $form->{selecttaxzone} .=
-          "<option value=$item->{id}>$item->{description}</option>";
+          "<option value=$item->{id}>" . H($item->{description}) . "</option>";
       }
 
     }
   } else {
     $form->{selecttaxzone} =~ s/ selected//g;
     if ($form->{taxzone_id} ne "") {
-      $form->{selecttaxzone} =~ s/value=$form->{taxzone_id}/value=$form->{taxzone_id} selected/;
+      $form->{selecttaxzone} =~ s/value=$form->{taxzone_id}>/value=$form->{taxzone_id} selected>/;
     }
   }
 
-  if ($form->{rowcount} >0) {
-    $form->{selecttaxzone} =~ /<option value=\d+ selected>.*?<\/option>/;
-    $form->{selecttaxzone} = $&;
-  }
-  
-
   $taxzone = qq|
              <tr>
                <th align=right>| . $locale->text('Steuersatz') . qq|</th>
                      <td>$form->{creditlimit}</td>
                      <td width=20%></td>
                      <th nowrap>| . $locale->text('Remaining') . qq|</th>
-                     <td class="plus$n">$form->{creditremaining}</td>
+                     <td class="plus$n" nowrap>$form->{creditremaining}</td>
                    </tr>
                  </table>
                </td>
     $onload = qq|alert('$credittext')|;
   }
 
+  $form->{"javascript"} .= qq|<script type="text/javascript" src="js/show_form_details.js">|;
+
   $form->header;
 
   print qq|
 </table>
 
 | . $locale->text("Edit the $form->{type}") . qq|<br>
-<input class=submit type=submit name=action value="|
+<input class=submit type=submit name=action id=update_button value="|
     . $locale->text('Update') . qq|">
 <input class=submit type=submit name=action value="|
     . $locale->text('Ship to') . qq|">
     . qq|</a></th>|;
   $column_header{quonumber} =
       qq|<th><a class=listheading href=$href&sort=quonumber>|
-    . $locale->text('Quotation')
+    . ($form->{"type"} eq "request_quotation" ?
+       $locale->text('RFQ') :
+       $locale->text('Quotation'))
     . qq|</a></th>|;
   $column_header{name} =
     qq|<th><a class=listheading href=$href&sort=name>$name</a></th>|;
 
   $form->{cp_id} *= 1;
 
+  for $i (1 .. $form->{rowcount}) {
+    map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig,
+                                                     $form->{"${_}_${i}"})
+            if ($form->{"${_}_${i}"}) }
+        qw(ship qty sellprice listprice basefactor));
+  }
+
   if (   $form->{type} =~ /_order/
       && $form->{currency} ne $form->{defaultcurrency}) {
 
   # if not it's most likely a collective order, which can't be saved back
   # so they just have to be closed
   if (($form->{ordnumber} ne '') || ($form->{quonumber} ne '')) {
-    relink_accounts();
-    OE->save(\%myconfig, \%$form);
+    OE->close_order(\%myconfig, \%$form);
   } else {
     OE->close_orders(\%myconfig, \%$form);
   }
 
   if (   $form->{type} eq 'sales_quotation'
       || $form->{type} eq 'request_quotation') {
-    $form->{closed} = 1;
-    relink_accounts();
-    OE->save(\%myconfig, \%$form);
+    OE->close_order(\%myconfig, \%$form);
   }
 
   $form->{cp_id} *= 1;
 
   if (   $form->{type} eq 'sales_quotation'
       || $form->{type} eq 'request_quotation') {
-    $form->{closed} = 1;
-    relink_accounts();
-    OE->save(\%myconfig, \%$form);
+    OE->close_order(\%myconfig, $form);
   }
 
   $form->{cp_id} *= 1;
   map { delete $form->{$_} }
     qw(id subject message cc bcc printed emailed queued customer vendor creditlimit creditremaining discount tradediscount oldinvtotal);
 
+  for $i (1 .. $form->{rowcount}) {
+    map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig,
+                                                     $form->{"${_}_${i}"})
+            if ($form->{"${_}_${i}"}) }
+        qw(ship qty sellprice listprice basefactor));
+  }
+
   &order_links;
 
   &prepare_order;
 
 
   $form->{title} = $locale->text('Reconciliation');
 
+  $form->{"jsscript"} = 1;
   $form->header;
 
   print qq|
        </tr>
        <tr>
          <th align=right>| . $locale->text('From') . qq|</th>
-         <td><input name=fromdate size=11 title="$myconfig{dateformat}"></td>
+         <td><input name=fromdate id=fromdate size=11 title="$myconfig{dateformat}">
+     <input type="button" name="fromdate" id="trigger_fromdate" value="?"></td>
          <th align=right>| . $locale->text('Until') . qq|</th>
-         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+         <td><input name=todate id=todate size=11 title="$myconfig{dateformat}">
+     <input type="button" name="todate" id="trigger_todate" value="?"></td>
        </tr>
       </table>
     </td>
   </tr>
 </table>
 
+| . $form->write_trigger(\%myconfig, 2,
+                         "fromdate", "BL", "trigger_fromdate",
+                         "todate", "BL", "trigger_todate") . qq|
+
 <br>
 <input type=hidden name=nextsub value=get_payments>
 
 
          <th align=right colspan=4>|
       . $locale->text('Decimalplaces')
       . qq|</th>
-             <td><input name=decimalplaces size=3></td>
+             <td><input name=decimalplaces size=3 value="2"></td>
          </tr>
                                     
 $jsscript
        </tr>
        <tr>
          <th align=right>| . $locale->text('Decimalplaces') . qq|</th>
-         <td><input name=decimalplaces size=3></td>
+         <td><input name=decimalplaces size=3 value="2"></td>
        </tr>
       </table>
     </td>
   $form->{IN} = "balance_sheet.html";
 
   # setup company variables for the form
-  map { $form->{$_} = $myconfig{$_} }
+  map { $form->{$_} = $myconfig{$_};
+        $form->{$_} =~ s/\\n/\n/g; }
     (qw(company address businessnumber nativecurr));
 
   $form->{templates} = $myconfig{templates};
 
     $ml = ($ref->{category} =~ /(A|C|E)/) ? -1 : 1;
 
-    $debit  = $form->format_amount(\%myconfig, $ref->{debit},  2, " ");
-    $credit = $form->format_amount(\%myconfig, $ref->{credit}, 2, " ");
+    $debit  = ($ref->{debit} != 0) ? $form->format_amount(\%myconfig, $ref->{debit},  2, " ") : " ";
+    $credit = ($ref->{credit} != 0) ? $form->format_amount(\%myconfig, $ref->{credit}, 2, " ") : " ";
     $begbalance =
       $form->format_amount(\%myconfig, $ref->{balance} * $ml, 2, " ");
     $endbalance =
       $i++;
 
       if ($subtotal) {
-        $c0subtotal =
-          $form->format_amount(\%myconfig, $c0subtotal, 2, " ");
-        $c30subtotal =
-          $form->format_amount(\%myconfig, $c30subtotal, 2, " ");
-        $c60subtotal =
-          $form->format_amount(\%myconfig, $c60subtotal, 2, " ");
-        $c90subtotal =
-          $form->format_amount(\%myconfig, $c90subtotal, 2, " ");
+        $c0subtotal = ($c0subtotal != 0) ? 
+          $form->format_amount(\%myconfig, $c0subtotal, 2, " ") : "";
+        $c30subtotal = ($c30subtotal != 0) ?
+          $form->format_amount(\%myconfig, $c30subtotal, 2, " ") : "";
+        $c60subtotal = ($c60subtotal != 0) ?
+          $form->format_amount(\%myconfig, $c60subtotal, 2, " ") : "";
+        $c90subtotal = ($c90subtotal != 0) ?
+          $form->format_amount(\%myconfig, $c90subtotal, 2, " ") : "";
       }
 
       $column_data{ct}        = qq|<th> </th>|;
     $c60total += $ref->{c60};
     $c90total += $ref->{c90};
 
-    $ref->{c0}  = $form->format_amount(\%myconfig, $ref->{c0},  2, " ");
-    $ref->{c30} = $form->format_amount(\%myconfig, $ref->{c30}, 2, " ");
-    $ref->{c60} = $form->format_amount(\%myconfig, $ref->{c60}, 2, " ");
-    $ref->{c90} = $form->format_amount(\%myconfig, $ref->{c90}, 2, " ");
+    $ref->{c0}  = ($ref->{c0} != 0) ? $form->format_amount(\%myconfig, $ref->{c0},  2, " ") : "";
+    $ref->{c30} = ($ref->{c30} != 0) ? $form->format_amount(\%myconfig, $ref->{c30}, 2, " ") : "";
+    $ref->{c60} = ($ref->{c60} != 0) ?  $form->format_amount(\%myconfig, $ref->{c60}, 2, " ") : "";
+    $ref->{c90} = ($ref->{c90} != 0) ?  $form->format_amount(\%myconfig, $ref->{c90}, 2, " ") : "";
 
     $href =
       qq|$ref->{module}.pl?path=$form->{path}&action=edit&id=$ref->{id}&login=$form->{login}&password=$form->{password}&callback=|
   $lxdebug->enter_sub();
 
   $form->{sendmode} = "attachment";
-  $form->{copies}   = 2 unless $form->{copies};
+
+  $form->{"format"} =
+    $form->{"format"} ? $form->{"format"} :
+    $myconfig{"template_format"} ? $myconfig{"template_format"} :
+    "pdf";
+
+  $form->{"copies"} =
+    $form->{"copies"} ? $form->{"copies"} :
+    $myconfig{"copies"} ? $myconfig{"copies"} :
+    2;
 
   $form->{PD}{ $form->{type} }     = "selected";
   $form->{DF}{ $form->{format} }   = "selected";
 
   $form->{title} = $locale->text('UStVA');
   $form->{kz10}  = '';                       #Berichtigte Anmeldung? Ja =1 Nein=0
 
-  my $year = substr(
-                    $form->datetonum($form->current_date(\%myconfig),
-                                     \%myconfig
-                    ),
-                    0, 4);
+  my $year = substr($form->datetonum($form->current_date(\%myconfig), \%myconfig ),
+             0, 4);
 
   my $department = '';
   local $hide = '';
   $form->header;
 
   print qq|
-<body>
-<form method=post action=$form->{script}>
+ <body>
+ <form method=post action=$form->{script}>
 
-<input type=hidden name=title value="$form->{title}">
+ <input type=hidden name=title value="$form->{title}">
 
-<table width=100%>
+ <table width=100%>
   <tr>
     <th class=listtop>$form->{title}</th>
   </tr>
     <td>
       <table>
       $department
-|;
+ |;
 
   # Hier Aufruf von get_config aus bin/mozilla/fa.pl zum
   # Einlesen der Finanzamtdaten
          <td width="50%" align="left" valign="top">
          <fieldset>
          <legend>
-         <b>| . $locale->text('Firma') . qq|</b>
+         <b>| . $locale->text('Company') . qq|</b>
          </legend>
   |;
   if ($form->{company} ne '') {
   } else {
     print qq|
            <a href=am.pl?path=$form->{path}&action=config&level=Programm--Preferences&login=$form->{login}&password=$form->{password}>
-           | . $locale->text('Kein Firmenname hinterlegt!') . qq|</a><br>
+           | . $locale->text('No Company Name given') . qq|!</a><br>
     |;
   }
 
     } else {
     print qq|
          <a href=am.pl?path=$form->{path}&action=config&level=Programm--Preferences&login=$form->{login}&password=$form->{password}>
-         | . $locale->text('Keine Firmenadresse hinterlegt!') . qq|</a>\n|;
+         | . $locale->text('No Company Address given') . qq|!</a>\n|;
   }
   $form->{co_email} = $form->{email} unless $form->{co_email};
   $form->{co_tel}   = $form->{tel}   unless $form->{co_tel};
   print qq|
          <br>
          <br>
-         | . $locale->text('Tel.: ') . qq|
+         | . $locale->text('Tel') . qq|.: 
          $form->{co_tel}
          <br>
-         | . $locale->text('Fax.: ') . qq|
+         | . $locale->text('Fax') . qq|.:nbsp;
          $form->{co_fax}         
          <br>
          <br>
          $form->{co_email}       
          <br>
          <br>
-         | . $locale->text('Steuernummer: ') . qq|
+         | . $locale->text('Tax Number') . qq|: 
   |;
 
   if ($form->{steuernummer} ne '') {
   }
   print qq|
          <br>
-         | . $locale->text('ELSTER-Steuernummer: ') . qq|
+         | . $locale->text('ELSTER Tax Number') . qq|: 
          $form->{elstersteuernummer}
           <br>
           <br>
          <fieldset>
          <legend>
             <input checked="checked" title="|
-      . $locale->text('Beraterdaten in UStVA übernehmen?')
+      . $locale->text('Assume Tax Consultant Data in Tax Computation?')
       . qq|" name="FA_steuerberater" id=steuerberater class=checkbox type=checkbox value="1"> 
-            <b>| . $locale->text('Steuerberater/-in') . qq|</b>
+            <b>| . $locale->text('Tax Consultant') . qq|</b>
             </legend>
             
             $form->{FA_steuerberater_name}<br>
   print qq|
          <fieldset>
          <legend>
-          <b>| . $locale->text('Voranmeldezeitraum') . qq|</b>
+          <b>| . $locale->text('Tax Period') . qq|</b>
          </legend>
   |;
   &ustva_vorauswahl();
   print qq|
            <input name="FA_10" id=FA_10 class=checkbox type=checkbox value="1" $checked title = "|
     . $locale->text(
-      'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)')
+      'Amended Advance Turnover Tax Return (Nr. 10)')
     . qq|">
-            | . $locale->text('Berichtigte Anmeldung') . qq|
+            | . $locale->text('Amended Advance Turnover Tax Return') . qq|
           <br>
   |;
 
           <br>
           | . $locale->text($voranmeld) . qq|
   |;
-    print qq| mit Dauerfristverlängerung| if ($form->{FA_dauerfrist} eq '1');
+    print $locale->text('With Extension Of Time') if ($form->{FA_dauerfrist} eq '1');
     print qq|
 
       <br>
     <td width="50%" valign="top">        
          <fieldset>
          <legend>
-         <b>| . $locale->text('Finanzamt') . qq|</b>
+         <b>| . $locale->text('Tax Office') . qq|</b>
          </legend>
           <h3>$form->{FA_Name}</h2>
     |;
           $form->{FA_PLZ}   $form->{FA_Ort}
           <br>
           <br>
-          | . $locale->text('Tel. : ') . qq|
+          | . $locale->text('Tel') . qq|.: 
           $form->{FA_Telefon}
           <br> 
-          | . $locale->text('Fax. : ') . qq|
+          | . $locale->text('Fax') . qq|.:$nbsp;
           $form->{FA_Fax}
           <br>
           <br>
           </a>
           <br>
           <br>
-          | . $locale->text('Öffnungszeiten') . qq|
+          | . $locale->text('Openings') . qq|
           <br>
           $oeffnungszeiten
           <br>
     if ($FA_1 && $FA_2) {
       print qq|
           <br>
-          | . $locale->text('Bankverbindungen') . qq|
+          | . $locale->text('Bank Connection') . qq|
           <table>
           <tr>
           <td>
           $form->{FA_Bankbezeichnung_1}
           <br>                  
-          | . $locale->text('Konto: ') . qq|
+          | . $locale->text('Account') . qq|: 
           $form->{FA_Kontonummer_1}
           <br>
-          | . $locale->text('BLZ: ') . qq|
+          | . $locale->text('Bank Code') . qq|: 
           $form->{FA_BLZ_1}
           </td>
           <td>
           $form->{FA_Bankbezeichnung_oertlich}
           <br>
-          | . $locale->text('Konto: ') . qq|
+          | . $locale->text('Account') . qq|: 
           $form->{FA_Kontonummer_2}
           <br> 
-          | . $locale->text('BLZ: ') . qq|
+          | . $locale->text('Bank Code') . qq|: 
           $form->{FA_BLZ_2}
           </td>
           </tr>
     } elsif ($FA_1) {
       print qq|
           <br>
-          | . $locale->text('Bankverbindung') . qq|
+          | . $locale->text('Bank Connection') . qq|
           <br>
           <br>
           $form->{FA_Bankbezeichnung_1}
           <br>                  
-          | . $locale->text('Konto: ') . qq|
+          | . $locale->text('Account') . qq|: 
           $form->{FA_Kontonummer_1}
           <br> 
-          | . $locale->text('BLZ: ') . qq|
+          | . $locale->text('Bank Code') . qq|: 
           $form->{FA_BLZ_1}          <br>
           <br>|;
     } elsif ($FA_2) {
       print qq|
           <br>
-          | . $locale->text('Bankverbindung') . qq|
+          | . $locale->text('Bank Connection') . qq|
           <br>
           <br>
           $form->{FA_Bankbezeichnung_oertlich}
           <br>                  
-          | . $locale->text('Konto: ') . qq|
+          | . $locale->text('Account') . qq|: 
           $form->{FA_Kontonummer_2}
           <br> 
-          | . $locale->text('BLZ: ') . qq|
+          | . $locale->text('Bank Code') . qq|: 
           $form->{FA_BLZ_2}
      |;
     }
       <br>
       <fieldset>
       <legend>
-      <b>| . $locale->text('Ausgabeformat') . qq|</b>
+      <b>| . $locale->text('Outputformat') . qq|</b>
       </legend>
   |;
 
      <td width="50%" valign="bottom">
      <fieldset>
      <legend>
-     <b>| . $locale->text('Hinweise') . qq|</b>
+     <b>| . $locale->text('Hints') . qq|</b>
      </legend>
       <h2 class="confirm">|
       . $locale->text('Missing Preferences: Outputroutine disabled')
       . qq|</h2>
-      <h3>| . $locale->text('Help:') . qq|</h3>
+      <h3>| . $locale->text('Help') . qq|</h3>
       <ul>
       <li>| . $locale->text('Hint-Missing-Preferences') . qq|</li>
       </ul>
    </td>
    <td align="right">
 
-    <!--</form>
+    </form>
+    <!--
     <form action="doc/ustva.html" method="get">
-    -->
+    
        <input type=submit class=submit name=action value="|
     . $locale->text('Help') . qq|">
-   <!-- </form>-->
+   </form>-->
    </td>
   </tr>
   </table>
   SWITCH: {
       $yymmdd <= ($yy + 110 + $dfv) && do {
         $form->{year} = $form->{year} - 1;
-        $sel = 'D';
+        $sel = '44';
         last SWITCH;
       };
       $yymmdd <= ($yy + 410 + $dfv) && do {
-        $sel = 'A';
+        $sel = '41';
         last SWITCH;
       };
       $yymmdd <= ($yy + 710 + $dfv) && do {
-        $sel = 'B';
+        $sel = '42';
         last SWITCH;
       };
       $yymmdd <= ($yy + 1010 + $dfv) && do {
-        $sel = 'C';
+        $sel = '43';
         last SWITCH;
       };
       $yymmdd <= ($yy + 1231) && do {
-        $sel = 'D';
+        $sel = '44';
       };
     }
 
   my $media  = qq|      <input type=hidden name="media" value="screen">|;
   my $format =
       qq|       <option value=html selected>|
-    . $locale->text('Vorschau')
+    . $locale->text('Preview')
     . qq|</option>|;
   if ($latex_templates) {
     $format .=
         qq|    <option value=pdf>|
-      . $locale->text('UStVA als PDF-Dokument')
+      . $locale->text('UStVA (PDF-Dokument)')
       . qq|</option>|;
   }
 
   if ($form->{elster} eq '1') {
     $format .=
         qq|<option value=elsterwinston>|
-      . $locale->text('ELSTER Export nach Winston')
+      . $locale->text('ELSTER Export (Winston)')
       . qq|</option>|
       . qq|<option value=elstertaxbird>|
-      . $locale->text('ELSTER Export nach Taxbird')
+      . $locale->text('ELSTER Export (Taxbird)')
       . qq|</option>|;      
   }
 
     $type
     $media
     <select name=format title = "|
-    . $locale->text('Ausgabeformat auswählen...') . qq|">$format</select>
+    . $locale->text('Choose Outputformat') . qq|">$format</select>
   |;
   $lxdebug->leave_sub();
 }
 
   get_config($userspath, 'finanzamt.ini');
 
-  # form vars initialisieren
+  # init some form vars
   my @anmeldungszeitraum =
     qw('0401' '0402' '0403' '0404' '0405' '0405' '0406' '0407' '0408' '0409' '0410' '0411' '0412' '0441' '0442' '0443' '0444');
   foreach my $item (@anmeldungszeitraum) {
                         qq|Actual year from Database: $form->{year}\n|);
     }
 
+    #
+    # using dates in ISO-8601 format: yyyymmmdd  for Postgres...
+    #
+    
     #yearly report
     if ($form->{period} eq "13") {
       $form->{fromdate} = "$form->{year}0101";
       };
     }
 
-  # using dates in ISO-8601 format: yyyymmmdd  for Postgres...
+
+
+
+  # Get the USTVA
   USTVA->ustva(\%myconfig, \%$form);
 
   # reformat Dates to dateformat
   $form->{fromdate} = $locale->date(\%myconfig, $form->{fromdate}, 0, 0, 0);
 
-  $form->{todate} = $form->current_date($myconfig) unless $form->{todate};
+  $form->{todate} = $form->current_date(\%myconfig) unless $form->{todate};
   $form->{todate} = $locale->date(\%myconfig, $form->{todate}, 0, 0, 0);
 
   $form->{longperiod} =
     $form->{longperiod}      =
         $locale->text('for Period')
       . qq|<br>\n$longfromdate |
-      . $locale->text('bis')
+      . $locale->text('to (date)')
       . qq| $longtodate|;
   }
 
     $form->{last_period} = "$shortcomparefromdate<br>\n$shortcomparetodate";
     $form->{longperiod} .=
         "<br>\n$longcomparefromdate "
-      . $locale->text('bis')
+      . $locale->text('to (date)')
       . qq| $longcomparetodate|;
   }
 
     $locale->date(\%myconfig, $form->current_date(\%myconfig), 0, 0, 0);
 
   # setup variables for the form
-  # steuernummer für prerelease entfernt
   my @a = qw(company businessnumber tel fax email
     co_chief co_department co_custom1 co_custom2 co_custom3 co_custom4 co_custom5
     co_name1 co_name2  co_street co_street1 co_zip co_city co_city1 co_country co_tel co_tel1 co_tel2
     $form->{co_city} =~ s/\\n//g;
   }
 
+  #
+  # Outputformat specific customisation's
+  #
+
+  my @category_cent = qw(511 861 36 80 971 931 98 96 53 74
+    85 65 66 61 62 67 63 64 59 69 39 83
+    Z43 Z45 Z53 Z62 Z65 Z67);
+
+  my @category_euro = qw(41 44 49 43 48 51 86 35 77 76 91 97 93
+    95 94 42 60 45 52 73 84);
+
   if ( $form->{format} eq 'pdf' or $form->{format} eq 'postscript') {
 
     $form->{IN} = "$form->{type}-$form->{year}.tex";
-
     $form->{padding} = "~~";
     $form->{bold}    = "\textbf{";
     $form->{endbold} = "}";
     $form->{br}      = '\\\\';
 
-    my @numbers = qw(511 861 36 80 971 931 98 96 53 74
-      85 65 66 61 62 Z67 63 64 59 69 39 83
-      Z43 Z45 Z53 Z62 Z65);
-
-    my $number = '';
-
     # Zahlenformatierung für Latex USTVA Formulare
-    if (   $myconfig{numberformat} eq '1.000,00'
-           or $myconfig{numberformat} eq '1000,00') {
-      foreach $number (@numbers) {
-        $form->{$number} =~ s/,/~~/g;
-      }
-    }
-    if (   $myconfig{numberformat} eq '1000.00'
-        or $myconfig{numberformat} eq '1,000.00') {
-      foreach $number (@numbers) {
-        $form->{$number} =~ s/\./~~/g;
-      }
+
+    foreach my $number (@category_euro) {
+      $form->{$number} = $form->format_amount(\%myconfig, $form->{$number}, '0', '');
     }
-    if ( $form->{period} eq '13'){ #Catch yearly USTE for now, not yet implemented.
-      $form->header;
-      USTVA::error(
-        $locale->text(
-        'Impossible to create yearly Tax Report as PDF or Postscript<br \> Not yet implemented!'
-        )
-      );
+
+    my ${decimal_comma} = ( $myconfig{numberformat} eq '1.000,00'
+         or $myconfig{numberformat} eq '1000,00' ) ? ',':'.';
+
+    foreach my $number (@category_cent) {
+      $form->{$number} = $form->format_amount(\%myconfig, $form->{$number}, '2', '');
+      $form->{$number} =~ s/${decimal_comma}/~~/g;
     }
-      
+
   } elsif ( $form->{format} eq 'html') { # Formatierungen für HTML Ausgabe
 
     $form->{IN} = $form->{type} . '.html';
     $form->{bold}    = "<b>";
     $form->{endbold} = "</b>";
     $form->{br}      = "<br>";
-    $form->{address} =~ s/\\n/<br \/>/g;
-
-  } elsif ($form->{format} =~ /^elster/) {
+    $form->{address} =~ s/\\n/\n/g;
 
-    if ( $form->{period} eq '13' ) {
-      $form->header;
-      USTVA::info(
-        $locale->text(
-        'Impossible to create yearly Tax Report via Winston or Taxbird.<br \> Not yet implemented!'
-      ));
+    foreach $number (@category_cent) {
+      $form->{$number} = $form->format_amount(\%myconfig, $form->{$number}, '2', '0');
     }
+    
+    foreach $number (@category_euro) {
+      $form->{$number} = $form->format_amount(\%myconfig, $form->{$number}, '0', '0');
+    }
+
+  } elsif ( $form->{format} eq 'elsterwinston' ) {
 
-    if ( $form->{format} eq 'elsterwinston' ) {
-
-      $form->{IN} = 'winston.xml';
-     
-      # Build Winston filename
-      my $file = 'U';     # 1. char 'U' = USTVA
-      $file .= $form->{period};
-      #4. and 5. char = year modulo 100
-      $file .= sprintf("%02d", $form->{year} % 100);
-      #6. to 18. char = Elstersteuernummer
-      #Beispiel: Steuernummer in Bayern
-      #111/222/33334 ergibt für UStVA Jan 2004: U01049111022233334
-      $file .= $form->{elsterFFFF};
-      $file .= $form->{elstersteuernummer};
-      #file suffix
-      $file .= '.xml';
-      $form->{tmpfile} = "$userspath/$file";
+    $form->{IN} = 'winston.xml';
+    
+    #
+    # Build Winston filename
+    #
+    
+    my $file = 'U';     # 1. char 'U' = USTVA
+    $file .= $form->{period};
+    #4. and 5. char = year modulo 100
+    $file .= sprintf("%02d", $form->{year} % 100);
+    #6. to 18. char = Elstersteuernummer
+    #Beispiel: Steuernummer in Bayern
+    #111/222/33334 ergibt für UStVA Jan 2004: U01049111022233334
+    $file .= $form->{elsterFFFF};
+    $file .= $form->{elstersteuernummer};
+    #file suffix
+    $file .= '.xml';
+    $form->{tmpfile} = "$userspath/$file";
+
+    $form->{attachment_filename} = "$file";
+ 
+    # Zahlenformatierung für Winston
+
+    my $temp_numberformat = $myconfig{numberformat};
+
+    # Numberformat must be '1000.00' for Winston
+
+    $myconfig{numberformat} = '1000.00';
+
+    foreach my $number (@category_cent) {
+      $form->{$number} = ( $form->{$number} !=0 ) ? $form->format_amount(\%myconfig, $form->{$number}, '2', '') : '';
+    }
+    
+    foreach my $number (@category_euro) {
+      $form->{$number} = ( $form->{$number} !=0 ) ? $form->format_amount(\%myconfig, $form->{$number}, '0', '') : '';
     }
+    # Re-set Numberformat
+    $myconfig{numberformat} = $temp_numberformat;
 
-    if ( $form->{format} eq 'elstertaxbird' ) {
+  }
+
+  elsif ( $form->{format} eq 'elstertaxbird' ) {
 
-      $form->{IN} = 'taxbird.txb';
-     
-      $form->{tmpfile} = "$userspath/USTVA-" . $form->{period} 
-      . sprintf("%02d", $form->{year} % 100) . ".txb";
+    $form->{IN} = 'taxbird.txb';
 
-      if ($form->{period} =~ /^[4]\d$/ ){
-        my %periods = ( # Lx => taxbird
-                     '41' => '12',
-                     '42' => '13',
-                     '43' => '14',
-                     '44' => '15',
-                   );
+    $form->{attachment_filename} = "USTVA-" . $form->{period} 
+    . sprintf("%02d", $form->{year} % 100) . ".txb";
+    
+    $form->{tmpfile} = "$userspath/" . $form->{attachment_filename};
+
+    if ($form->{period} =~ /^[4]\d$/ ){
+      my %periods = ( # Lx => taxbird
+                   '41' => '12',
+                   '42' => '13',
+                   '43' => '14',
+                   '44' => '15',
+                 );
+    
+      foreach my $quarter ( keys %periods ) {
+        $form->{taxbird_period} = $periods{$quarter} if ( $form->{period} eq $quarter);
+      }
+      
+      my %lands = ( # Lx => taxbird # TODO: besser als array...
+                  'Baden Würtemberg'       => '0',
+                  'Bayern'                 => '1',
+                  'Berlin'                 => '2',
+                  'Brandenburg'            => '3',
+                  'Bremen'                 => '4',
+                  'Hamburg'                => '5',
+                  'Hessen'                 => '6',
+                  'Mecklenburg Vorpommern' => '7',
+                  'Niedersachsen'          => '8',
+                  'Nordrhein Westfalen'    => '9',
+                  'Rheinland Pfalz'        => '10',
+                  'Saarland'               => '11',
+                  'Sachsen'                => '12',
+                  'Sachsen Anhalt'         => '13',
+                  'Schleswig Holstein'     => '14',
+                  'Thüringen'              => '15',
+            );
+
+      foreach my $land ( keys %lands ){
+        $form->{taxbird_land_nr} = $lands{$land} if ($form->{elsterland} eq $land );
+      }
       
-        foreach my $quarter ( keys %periods ) {
-          $form->{period} = $periods{$quarter} if ( $form->{period} eq $quarter);
-        }
-        
-        my %lands = ( # Lx => taxbird # TODO: besser als array...
-                    'Baden Würtemberg'       => '0',
-                    'Bayern'                 => '1',
-                    'Berlin'                 => '2',
-                    'Brandenburg'            => '3',
-                    'Bremen'                 => '4',
-                    'Hamburg'                => '5',
-                    'Hessen'                 => '6',
-                    'Mecklenburg Vorpommern' => '7',
-                    'Niedersachsen'          => '8',
-                    'Nordrhein Westfalen'    => '9',
-                    'Rheinland Pfalz'        => '10',
-                    'Saarland'               => '11',
-                    'Sachsen'                => '12',
-                    'Sachsen Anhalt'         => '13',
-                    'Schleswig Holstein'     => '14',
-                    'Thüringen'              => '15',
-              );
-
-
-        foreach my $land ( keys %lands ){
-          $form->{elsterland} = $lands{$land} if ($form->{elsterland} eq $land );
-        }
-      } elsif ($form->{period} =~ /^\d+$/ ) {
-        $form->{period} =~ s/^0//g;
-        my $period = $form->{period};
-        $period * 1;
-        $period--;
-        $form->{period} = $period;
-       } else {
-         $form->header;
-         USTVA::error( $locale->text('Wrong Period' ));
-         exit(0);
-                
-       }
+      $form->{taxbird_steuernummer} = $form->{steuernummer};
+      $form->{taxbird_steuernummer} =~ s/\D//g;
       
+      $form->{co_zip} = $form->{co_city};
+      $form->{co_zip} =~ s/\D//g;
+      $form->{co_city} =~ s/\d//g;
+      $form->{co_city} =~ s/^\s//g;
+      
+      ($form->{co_phone_prefix}, $form->{co_phone}) = split("-", $form->{tel});
+      
+      # Numberformatting for Taxbird
+
+      my $temp_numberformat = $myconfig{numberformat};
+      # Numberformat must be '1000.00' for Taxbird ?!
+
+      $myconfig{numberformat} = '1000.00';
+
+      foreach my $number (@category_cent) {
+        $form->{$number} = ( $form->{$number} !=0 ) ? $form->format_amount(\%myconfig, $form->{$number}, '2', '') : '';
+      }
+      
+      foreach my $number (@category_euro) {
+        $form->{$number} = ( $form->{$number} !=0 ) ? $form->format_amount(\%myconfig, $form->{$number}, '0', '') : '';
+      }
+      # Re-set Numberformat
+      $myconfig{numberformat} = $temp_numberformat;
+      
+    } elsif ($form->{period} =~ /^\d+$/ ) {
+      $form->{period} =~ s/^0//g;
+      my $period = $form->{period};
+      $period * 1;
+      $period--;
+      $form->{period} = $period;
+    } else {
+      $form->header;
+      USTVA::error( $locale->text('Wrong Period' ));
+      exit(0);
     }
-    # Other Elster formats follow here...
     
   } elsif ( $form->{format} eq '' ){ # No format error.
     $form->header;
-    USTVA::error( $locale->text('Application Error. No Format given!' ));
+    USTVA::error( $locale->text('Application Error. No Format given' ) . "!");
     exit(0);
  
   } else { # All other Formats are wrong
     $form->header;
-    USTVA::error( $locale->text('Application Error. Wrong Format: ') . $form->{format} );
+    USTVA::error( $locale->text('Application Error. Wrong Format') . ": " . $form->{format} );
     exit(0);
   }
+
+  if ( $form->{period} eq '13' and $form->{format} ne 'html') {
+    $form->header;
+    USTVA::info(
+      $locale->text(
+      'Yearly taxreport not yet implemented')
+      . '!');
+  }
     
-  
   $form->{templates} = $myconfig{templates};
   $form->{templates} = "doc" if ( $form->{type} eq 'help' );
 
-  $form->parse_template($myconfig, $userspath);
+  $form->parse_template(\%myconfig, $userspath);
 
   $lxdebug->leave_sub();
 }
     "$form->{cbscript}?action=edit&login=$form->{cblogin}&path=$form->{cbpath}&root=$form->{cbroot}&rpw=$form->{cbrpw}"
     if ($form->{cbscript} ne '' and $form->{cblogin} ne '');
 
-  $form->{title} = $locale->text('Finanzamt - Einstellungen');
+  $form->{title} = $locale->text('Tax Office Preferences');
   print qq|
     <body>
     <form name="verzeichnis" method=post action="$form->{script}">
      <table width=100%>
        <tr>
          <th class="listtop">|
-    . $locale->text('Finanzamt - Einstellungen') . qq|</th>
+    . $locale->text('Tax Office Preferences') . qq|</th>
        </tr>
         <tr>
          <td>
            <br>
            <fieldset>
            <legend><b>|
-    . $locale->text('Angaben zum Finanzamt') . qq|</b></legend>
+    . $locale->text('Local Tax Office Preferences') . qq|</b></legend>
   |;
 
   #print qq|$form->{terminal}|;
   $checked = "checked" if ($form->{method} eq 'accrual');
   print qq|
            <fieldset>
-           <legend><b>| . $locale->text('Verfahren') . qq|</b>
+           <legend><b>| . $locale->text('Taxation') . qq|</b>
            </legend>
            <input name=method id=accrual class=radio type=radio value="accrual" $checked>
            <label for="accrual">| . $locale->text('accrual') . qq|</label>
            </fieldset>
            <br>
            <fieldset>
-           <legend><b>| . $locale->text('Voranmeldungszeitraum') . qq|</b>
+           <legend><b>| . $locale->text('Tax Period') . qq|</b>
            </legend>
   |;
   $checked = '';
   print qq|
            <input name="FA_dauerfrist" id=FA_dauerfrist class=checkbox type=checkbox value="1" $checked>
            <label for="">|
-    . $locale->text('Dauerfristverlängerung') . qq|</label>
+    . $locale->text('Extension Of Time') . qq|</label>
            
            </fieldset>
            <br>
            <fieldset>
-           <legend><b>| . $locale->text('Steuerberater/-in') . qq|</b>
+           <legend><b>| . $locale->text('Tax Consultant') . qq|</b>
            </legend>
   |;
   $checked = '';
   print qq|
           <!-- <input name="FA_71" id=FA_71 class=checkbox type=checkbox value="X" $checked>
            <label for="FA_71">|
-    . $locale->text('Verrechnung des Erstattungsbetrages erwünscht (Zeile 71)')
+    . $locale->text('Clearing Tax Received (No 71)')
     . qq|</label>
            <br>
            <br>-->
            | . $locale->text('Name') . qq|
            </td>
            <td>
-           | . $locale->text('Straße') . qq|
+           | . $locale->text('Street') . qq|
            </td>
            <td>
-           | . $locale->text('PLZ, Ort') . qq|
+           | . $locale->text('Zip, City') . qq|
            </td>
            <td>
-           | . $locale->text('Telefon') . qq|
+           | . $locale->text('Telephone') . qq|
            </td>
            </tr>
            <tr>
            |;
   print qq|
            <input type="button" name="Verweis" value="|
-    . $locale->text('Back to user config...') . qq|" 
+    . $locale->text('User Config') . qq|" 
             onClick="self.location.href='$callback'">| if ($callback ne '');
   print qq|
               
           <input type=hidden name="nextsub" value="edit_form">
           <input type=hidden name="warnung" value="1">
           <input type=hidden name="saved" value="|
-    . $locale->text('Bitte Angaben überprüfen') . qq|">
+    . $locale->text('Check Details') . qq|">
           <input type=hidden name="path" value=$form->{path}>
           <input type=hidden name="login" value=$form->{login}>
           <input type=hidden name="password" value=$form->{password}>
    <table width="100%">
        <tr>
         <th colspan="2" class="listtop">|
-    . $locale->text('Finanzamt - Einstellungen') . qq|</th>
+    . $locale->text('Tax Office Preferences') . qq|</th>
        </tr>
        <tr>
          <td colspan=2>
            <br>
            <fieldset>
            <legend>
-           <font size="+1">| . $locale->text('Steuernummer') . qq|</font>
+           <font size="+1">| . $locale->text('Tax Number') . qq|</font>
            </legend>
            <br>
   |;
 
   print qq|
            <input type="button" name="Verweis" value="|
-    . $locale->text('Back to user config...') . qq|" 
+    . $locale->text('User Config') . qq|" 
             onClick="self.location.href='$form->{callback}'">|
     if ($form->{callback} ne '');
 
           <input type=submit class=submit name=action value="|
       . $locale->text('continue') . qq|">
           <input type=hidden name="saved" value="|
-      . $locale->text('Bitte alle Angaben überprüfen') . qq|">
+      . $locale->text('Check Details') . qq|">
     |;
   } else {
     print qq|
 
   } else {
 
-    $form->{saved} = $locale->text('Bitte eine Steuernummer angeben');
+    $form->{saved} = $locale->text('Choose a Tax Number');
   }
 
   &edit_form;
                <fieldset>
                <legend>
                <font size="+1">|
-    . $locale->text('Finanzamt') . qq| $form->{FA_Name}</font>
+    . $locale->text('Tax Office') . qq| $form->{FA_Name}</font>
                </legend>
   |;
 
                   <table width="100%">
                    <tr>
                     <td>
-                    | . $locale->text('Finanzamt') . qq|
+                    | . $locale->text('Tax Office') . qq|
                     </td>
                    </tr>
                    <tr>
                   <br>
                   <fieldset>
                   <legend>
-                  <b>| . $locale->text('Kontakt') . qq|</b>
+                  <b>| . $locale->text('Contact') . qq|</b>
                   </legend>
-                      | . $locale->text('Telefon') . qq|<br>
+                      | . $locale->text('Telephone') . qq|<br>
                       <input name="FA_Telefon" size="40" title="FA_Telefon" value="$form->{FA_Telefon}" $readonly>
                       <br>
                       <br> 
                   <br>
                   <fieldset>
                   <legend>
-                  <b>| . $locale->text('Öffnungszeiten') . qq|</b>
+                  <b>| . $locale->text('Openings') . qq|</b>
                   </legend>
                   <textarea name="FA_Oeffnungszeiten" rows="4" cols="40" $readonly>$oeffnungszeiten</textarea>
                   </fieldset>
                     <fieldset>
                     <legend>
                     <b>|
-      . $locale->text('Bankverbindungen des Finanzamts') . qq|</b>
+      . $locale->text('Bank Connection Tax Office') . qq|</b>
                     <legend>
                     <table>   
                     <tr>
                      <td>
-                        | . $locale->text('Kreditinstitut') . qq|
+                        | . $locale->text('Bank') . qq|
                         <br>
                         <input name="FA_Bankbezeichnung_1" size="30" value="$form->{FA_Bankbezeichnung_1}" $readonly>
                         <br>
                         <br>
-                        | . $locale->text('Kontonummer') . qq|
+                        | . $locale->text('Account Nummer') . qq|
                         <br>
                         <input name="FA_Kontonummer_1" size="15" value="$form->{FA_Kontonummer_1}" $readonly>
                         <br>
                         <br> 
-                        | . $locale->text('Bankleitzahl') . qq|
+                        | . $locale->text('Bank Code (long)') . qq|
                         <br>
                         <input name="FA_BLZ_1" size="15" value="$form->{FA_BLZ_1}" $readonly>
                      </td>
                      <td>
-                        | . $locale->text('Kreditinstitut') . qq|
+                        | . $locale->text('Bank') . qq|
                         <br>
                         <input name="FA_Bankbezeichnung_oertlich" size="30" value="$form->{FA_Bankbezeichnung_oertlich}" $readonly>
                         <br>
                         <br>
-                        | . $locale->text('Kontonummer') . qq|
+                        | . $locale->text('Account Nummer') . qq|
                         <br>
                         <input name="FA_Kontonummer_2" size="15" value="$form->{FA_Kontonummer_2}" $readonly>
                         <br>
                         <br> 
-                        | . $locale->text('Bankleitzahl') . qq|
+                        | . $locale->text('Bank Code (long)') . qq|
                         <br>
                         <input name="FA_BLZ_2" size="15" value="$form->{FA_BLZ_2}" $readonly>
                      </td>
                     <fieldset>
                     <legend>
                       <b>|
-      . $locale->text('Bankverbindung des Finanzamts') . qq|</b>
+      . $locale->text('Bank Connection Tax Office') . qq|</b>
                     <legend>
-                    | . $locale->text('Kontonummer') . qq|
+                    | . $locale->text('Account Nummer') . qq|
                     <br>
                     <input name="FA_Kontonummer_1" size="30" value="$form->{FA_Kontonummer_1}" $readonly>
                     <br>
                     <br> 
-                    | . $locale->text('Bankleitzahl (BLZ)') . qq|
+                    | . $locale->text('Bank Code (long)') . qq|
                     <br>
                     <input name="FA_BLZ_1" size="15" value="$form->{FA_BLZ_1}" $readonly>
                     <br>
                     <br>
-                    | . $locale->text('Kreditinstitut') . qq|
+                    | . $locale->text('Bank') . qq|
                     <br>
                     <input name="FA_Bankbezeichnung_1" size="15" value="$form->{FA_Bankbezeichnung_1}" $readonly>
                     <br>
                     <fieldset>
                     <legend>
                       <b>|
-      . $locale->text('Bankverbindung des Finanzamts') . qq|</b>
+      . $locale->text('Bank Connection Tax Office') . qq|</b>
                     <legend> 
-                    | . $locale->text('Kontonummer') . qq|
+                    | . $locale->text('Account Nummer') . qq|
                     <br>
                     <input name="FA_Kontonummer_2" size="30" value="$form->{FA_Kontonummer_2}" $readonly>
                     <br>
                     <br> 
-                    | . $locale->text('Bankleitzahl (BLZ)') . qq|
+                    | . $locale->text('Bank Code (long)') . qq|
                     <br>
                     <input name="FA_BLZ_2" size="15" value="$form->{FA_BLZ_2}" $readonly>
                     <br>
                     <br>
-                    | . $locale->text('Kreditinstitut') . qq|
+                    | . $locale->text('Bank') . qq|
                     <br>
                     <input name="FA_Bankbezeichnung_oertlich" size="15" value="$form->{FA_Bankbezeichnung_oertlich}" $readonly>
                     </fieldset>
 
--- /dev/null
+/* stylesheet for LX-Office ERP 
+Getestet mit W3C CSS-Validator: 
+Keine Fehler oder Warnungen gefunden
+*/
+
+A:link { color: black; text-decoration: none; }
+A:visited { color: black; text-decoration: none; }
+A:active { color: black; text-decoration: underline; }
+input:focus, textarea:focus, select:focus, option:focus { background-color: yellow; }
+A.nohover:hover { 
+  color:white;
+  background-color: #093280;
+  font-size: 10pt;
+  text-decoration: none;
+}
+A:hover { 
+  color:white;
+  background-color: #093280;
+  font-size: 10pt;
+  text-decoration: none;
+}
+body {
+  font-family: Verdana, Arial, Helvetica;
+  font-size: 10pt;
+  background-color: #D4D0C8;
+  color: black
+}
+td {
+  font-family: Verdana, Arial, Helvetica;
+  color: black;
+  font-size: 10pt;
+  font-weight: normal;
+}
+th {
+  font-family: Verdana, Arial, Helvetica;
+  color: black;
+  font-size: 10pt;
+  font-weight: normal;
+}
+/* login and admin */
+.login {
+  font-family: Verdana, Arial, Helvetica;
+}
+body.login {
+  background: #b8d1f3;
+  color: #D4D0C8;
+}
+h1.login {
+  font-size: 18pt;
+}
+table.login {
+  background-color: #efedde;
+  padding: 20px;
+}
+td.login {
+  text-align: center;
+}
+th.login {
+  text-align: right;
+}
+body.admin {
+  background-color:#ffffff;
+  color: black;
+}
+body.menu {
+  background-color: white;
+  font-family: Verdana, Arial, Helvetica;
+  font-size:10pt;
+  color: black;
+}
+.listtop { 
+  background-color: #b8d1f3; 
+  text-align:left;
+  padding:5px;
+  font-size: 10pt; 
+  color: black; 
+  font-weight: bolder;
+  border-bottom: 2px solid #A5A29C;
+}
+.listheading { 
+  font-size: 10pt; 
+  padding:3px;
+  background-color: #b8d1f3;
+  color: black; 
+  font-weight: bolder;
+  text-align:left;
+}       
+.subsubheading {
+  color: black;
+  font-weight: bolder;
+  text-decoration: underline;
+}
+.optionen {
+  border:dashed;
+  border-width:1px;
+  background:#D4D0C8;
+}
+/* Bei Listen den Farbwechsel zur besseren Lesbarkeit: */
+.listrow1 { background-color: #C8D4C6; color: black; vertical-align: top; }
+.listrow0 { background-color: white; color: black; vertical-align: top; }
+.listsubtotal { border-top: 1px solid black; font-size: 10pt; background-color: #b8d1f3; color: black; font-weight: bolder;}
+.listtotal { border-top: 1px double black; font-size: 10pt; background-color: #b8d1f3; color: black; font-weight: bolder;}
+.submit {
+  font-family: Verdana, Arial, Helvetica;
+  color: #000000;
+}
+.checkbox, .radio {
+  font-family: Verdana, Arial, Helvetica;
+  color: #778899;
+}
+.plus0 {    /* font color for negative numbers */
+  color: red;
+}
+.plus1 {
+  color: green;
+}
+h2.confirm {
+  color: blue;
+  font-size: 14pt;
+}
+h2.error {
+  color: red;
+  font-size: 14pt;
+}
+/* media stuff */
+@media screen {
+  .noscreen {   /* items with this class won't display */
+    display: none;
+  }
+}
+@media print {
+  .noprint {   /* items with this class won't print */
+    display: none;
+  }
+}
+
 
--- /dev/null
+<attach event="ondocumentready" handler="parseStylesheets" />\r
+<script>\r
+/**\r
+ *     Whatever:hover - V2.02.060206 - hover, active & focus\r
+ *     ------------------------------------------------------------\r
+ *     (c) 2005 - Peter Nederlof\r
+ *     Peterned - http://www.xs4all.nl/~peterned/\r
+ *     License  - http://creativecommons.org/licenses/LGPL/2.1/\r
+ *\r
+ *     Whatever:hover is free software; you can redistribute it and/or\r
+ *     modify it under the terms of the GNU Lesser General Public\r
+ *     License as published by the Free Software Foundation; either\r
+ *     version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ *     Whatever:hover is distributed in the hope that it will be useful,\r
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ *     Lesser General Public License for more details.\r
+ *\r
+ *     Credits and thanks to:\r
+ *     Arnoud Berendsen, Martin Reurings, Robert Hanson\r
+ *\r
+ *     howto: body { behavior:url("csshover.htc"); }\r
+ *     ------------------------------------------------------------\r
+ */\r
+\r
+var csshoverReg = /(^|\s)((([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active))|((a|input|textarea)([#.][^ ]+)?:unknown)/i,\r
+currentSheet, doc = window.document, hoverEvents = [], activators = {\r
+       onhover:{on:'onmouseover', off:'onmouseout'},\r
+       onactive:{on:'onmousedown', off:'onmouseup'},\r
+       onunknown:{on:'onfocus', off:'onblur'}\r
+}\r
+\r
+function parseStylesheets() {\r
+       if(!/MSIE (5|6)/.test(navigator.userAgent)) return;\r
+       window.attachEvent('onunload', unhookHoverEvents);\r
+       var sheets = doc.styleSheets, l = sheets.length;\r
+       for(var i=0; i<l; i++) \r
+               parseStylesheet(sheets[i]);\r
+}\r
+       function parseStylesheet(sheet) {\r
+               if(sheet.imports) {\r
+                       try {\r
+                               var imports = sheet.imports, l = imports.length;\r
+                               for(var i=0; i<l; i++) parseStylesheet(sheet.imports[i]);\r
+                       } catch(securityException){}\r
+               }\r
+\r
+               try {\r
+                       var rules = (currentSheet = sheet).rules, l = rules.length;\r
+                       for(var j=0; j<l; j++) parseCSSRule(rules[j]);\r
+               } catch(securityException){}\r
+       }\r
+\r
+       function parseCSSRule(rule) {\r
+               var select = rule.selectorText, style = rule.style.cssText;\r
+               if(!csshoverReg.test(select) || !style) return;\r
+               \r
+               var pseudo = select.replace(/[^:]+:([a-z-]+).*/i, 'on$1');\r
+               var newSelect = select.replace(/(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi, '.$2' + pseudo);\r
+               var className = (/\.([a-z0-9_-]*on(hover|active|unknown))/i).exec(newSelect)[1];\r
+               var affected = select.replace(/:(hover|active|unknown).*$/, '');\r
+               var elements = getElementsBySelect(affected);\r
+               if(elements.length == 0) return;\r
+\r
+               currentSheet.addRule(newSelect, style);\r
+               for(var i=0; i<elements.length; i++)\r
+                       new HoverElement(elements[i], className, activators[pseudo]);\r
+       }\r
+\r
+function HoverElement(node, className, events) {\r
+       if(!node.hovers) node.hovers = {};\r
+       if(node.hovers[className]) return;\r
+       node.hovers[className] = true;\r
+       hookHoverEvent(node, events.on, function() { node.className += ' ' + className; });\r
+       hookHoverEvent(node, events.off, function() { node.className = node.className.replace(new RegExp('\\s+'+className, 'g'),''); });\r
+}\r
+       function hookHoverEvent(node, type, handler) {\r
+               node.attachEvent(type, handler);\r
+               hoverEvents[hoverEvents.length] = { \r
+                       node:node, type:type, handler:handler \r
+               };\r
+       }\r
+\r
+       function unhookHoverEvents() {\r
+               for(var e,i=0; i<hoverEvents.length; i++) {\r
+                       e = hoverEvents[i]; \r
+                       e.node.detachEvent(e.type, e.handler);\r
+               }\r
+       }\r
+\r
+function getElementsBySelect(rule) {\r
+       var parts, nodes = [doc];\r
+       parts = rule.split(' ');\r
+       for(var i=0; i<parts.length; i++) {\r
+               nodes = getSelectedNodes(parts[i], nodes);\r
+       }       return nodes;\r
+}\r
+       function getSelectedNodes(select, elements) {\r
+               var result, node, nodes = [];\r
+               var identify = (/\#([a-z0-9_-]+)/i).exec(select);\r
+               if(identify) {\r
+                       var element = doc.getElementById(identify[1]);\r
+                       return element? [element]:nodes;\r
+               }\r
+               \r
+               var classname = (/\.([a-z0-9_-]+)/i).exec(select);\r
+               var tagName = select.replace(/(\.|\#|\:)[a-z0-9_-]+/i, '');\r
+               var classReg = classname? new RegExp('\\b' + classname[1] + '\\b'):false;\r
+               for(var i=0; i<elements.length; i++) {\r
+                       result = tagName? elements[i].all.tags(tagName):elements[i].all; \r
+                       for(var j=0; j<result.length; j++) {\r
+                               node = result[j];\r
+                               if(classReg && !classReg.test(node.className)) continue;\r
+                               nodes[nodes.length] = node;\r
+                       }\r
+               }       \r
+               \r
+               return nodes;\r
+       }\r
+</script>
\ No newline at end of file
 
   font-size: 10pt;
   background-color: white;
   background-image: url("../image/fade.png"); background-repeat:repeat-x;
-  color: black
+  color: black;
 }
-// .bg { background-image: url("mn_hauptmenu.png");}
+
+/* .bg { 
+  background-image: url("mn_hauptmenu.png"); 
+} */
+
 td {
   font-family: Verdana, Arial, Helvetica;
   color: black;
     display: none;
   }
 }
+
 
--- /dev/null
+body {\r
+behavior:url("css/csshover.htc");\r
+}\r
+\r
+#menu{\r
+width:100%;\r
+float:left;\r
+}\r
+\r
+#menu a, #menu h2, #menu div.x {\r
+font:11px/16px arial,helvetica,sans-serif;\r
+display:block;\r
+border-width:1px;\r
+border-style:solid;\r
+border-color:#ccc #888 #555 #bbb;\r
+white-space:nowrap;\r
+margin:0;\r
+padding:1px 0 1px 3px;\r
+}\r
+\r
+#menu h2{\r
+color:#fff;\r
+background:#000 url(../image/bg_css_menu.png) repeat 100% 100%;\r
+}\r
+\r
+#menu a{\r
+background:#eee;\r
+text-decoration:none;\r
+}\r
+\r
+#menu a, #menu a:visited{\r
+color:#000;\r
+}\r
+\r
+#menu a:hover{\r
+color:#a00;\r
+background:#ddd;\r
+}\r
+\r
+#menu a:active{\r
+color:#060;\r
+background:#ccc;\r
+}\r
+\r
+#menu ul{\r
+list-style:none;\r
+margin:0;\r
+padding:0;\r
+float:left;\r
+min-width:7em;\r
+}\r
+\r
+#menu li{\r
+position:relative;\r
+}\r
+\r
+#menu ul ul{\r
+position:absolute;\r
+z-index:500;\r
+top:auto;\r
+display:none;\r
+}\r
+\r
+#menu ul ul ul{\r
+top:0;\r
+left:100%;\r
+}\r
+\r
+/* Begin non-anchor hover selectors */\r
+\r
+/* Enter the more specific element (div) selector\r
+on non-anchor hovers for IE5.x to comply with the\r
+older version of csshover.htc - V1.21.041022. It\r
+improves IE's performance speed to use the older\r
+file and this method */\r
+\r
+div#menu h2:hover{\r
+background:#A3C5FF url(../image/expand3.gif) no-repeat -999px -9999px;\r
+color:#a00;\r
+}\r
+\r
+div#menu li:hover{\r
+cursor:pointer;\r
+z-index:100;\r
+}\r
+\r
+div#menu li:hover ul ul,\r
+div#menu li li:hover ul ul,\r
+div#menu li li li:hover ul ul,\r
+div#menu li li li li:hover ul ul\r
+{display:none;}\r
+\r
+div#menu li:hover ul,\r
+div#menu li li:hover ul,\r
+div#menu li li li:hover ul,\r
+div#menu li li li li:hover ul\r
+{display:block;}\r
+\r
+/* End of non-anchor hover selectors */\r
+\r
+/* Styling for Expand */\r
+\r
+#menu a.x, #menu a.x:visited{\r
+/*font-weight:bold;*/\r
+color:#000;\r
+background:#eee url(../image/expand3.gif) no-repeat 100% 100%;\r
+}\r
+\r
+#menu a.x:hover{\r
+color:#fff;\r
+background:#000;\r
+}\r
+\r
+#menu a.x:active{\r
+color:#060;\r
+background:#ccc;\r
+}\r
+\r
+#menu div.x, #menu div.x:visited{\r
+/*font-weight:bold;*/\r
+color:#000;\r
+background:#eee url(../image/expand3.gif) no-repeat 100% 100%;\r
+}\r
+\r
+#menu div.x:hover{\r
+color:#a00;\r
+background:#ddd;\r
+}\r
+\r
+#menu div.x:active{\r
+color:#060;\r
+background:#ccc;\r
+}\r
 
 Nach der Installation müssen in der Datei "lx-erp.conf" zwei weitere
 Variablen angepasst werden: "$openofficeorg_writer_bin" muss den
 vollständigen Pfad zur OpenOffice.org Writer-Anwendung enthalten.
-"$xvfb_run_bin" muss den Pfad zu einem Script enthalten, dass den "X
-virtual frame buffer" startet und direkt danach ein Programm in ihm
-startet, das dem Script als Parameter übergeben wird. Lx-Office
-enthält bereits ein solches Script namens "xvfb-run", das
-standardmäßig verwendet wird. Es handelt sich dabei um eine gestutzte
-Version des Scripts "xvfb-run" aus dem Debian-Paket "xvfb".
+"$xvfb_bin" muss den Pfad zum "X virtual frame buffer" enthalten.
+
+Zusätzlich gibt es zwei verschiedene Arten, wie Lx-Office mit
+OpenOffice kommuniziert. Die erste Variante, die benutzt wird, wenn
+die Variable "$openofficeorg_daemon" gesetzt ist, startet ein
+OpenOffice, das auch nach der Umwandlung des Dokumentes gestartet
+bleibt. Bei weiteren Umwandlungen wird dann diese laufende Instanz
+benutzt. Der Vorteil ist, dass die Zeit zur Umwandlung deutlich
+reduziert wird, weil nicht für jedes Dokument ein OpenOffice gestartet
+werden muss. Der Nachteil ist, dass diese Methode Python und die
+Python-UNO-Bindings benötigt, die Bestandteil von OpenOffice 2 sind.
+
+Ist "$openofficeorg_daemon" nicht gesetzt, so wird für jedes Dokument
+OpenOffice neu gestartet und die Konvertierung mit Hilfe eines Makros
+durchgeführt. Dieses Makro muss in der Dokumentenvorlage enthalten
+sein und "Standard.Conversion.ConvertSelfToPDF()" heißen. Die
+Beispielvorlage templates/German-invoice.odt enthält ein solches
+Makro, das in jeder anderen Dokumentenvorlage ebenfalls enthalten sein
+muss.
 
 Als letztes muss herausgefunden werden, welchen Namen OpenOffice.org
 Writer dem Verzeichnis mit den Benutzereinstellungen gibt. Unter
 
 ** BITTE FERTIGEN SIE VOR DEM UPGRADE EIN BACKUP IHRER DATENBANK(EN) AN! **
 
 
+Upgrade von v2.4.0 auf 2.4.1
+============================
+
+Ein Upgrade von v2.4.0 auf v2.4.1 besteht aus zwei Teilen: den Dateien
+(einfaches Entpacken und Kopieren in das Installationsverzeichnis
+genügen) sowie dem Datenbankupgrade.
+
+Das Datenbankupgrade wird automatisch gestartet, wenn sich der erste
+Benutzer nach dem Upgrade der Dateien an Lx-Office anmeldet.
+
+** BITTE FERTIGEN SIE VOR DEM UPGRADE EIN BACKUP IHRER DATENBANK(EN) AN! **
+
+Anders als beim Upgrade auf 2.4.0 handelt es bei den Datenbankupgrades
+auf 2.4.1 nur um automatisch ablaufende Scripte, die keine
+Benutzereingaben erfordern.
+
+
 Upgrade von v2.2.0 bis 2.2.2 auf 2.4.0
---------------------------------------
+======================================
 
 Ein direktes Upgrade von den unmodifizierten Versionen 2.2.0, 2.2.1
-und 2.2.2 auf 2.4.0 ist möglich. Es solches Upgrade besteht aus zwei
+und 2.2.2 auf 2.4.0 ist möglich. Ein solches Upgrade besteht aus zwei
 Teilen: den Dateien (einfaches Entpacken und Kopieren in das
 Installationsverzeichnis genügen) sowie dem Datenbankupgrade.
 
 Wird in einer Verkaufs- oder Einkaufsmaske eine andere Steuerzone als
 Inland ausgewählt, werden bei den Artikeln auch automatisch die
 anderen Erlös- und Aufwandskonten der Buchungsgruppe verwendet.
+
+Dokumentenvorlagen, Umbennante Vorlagenvariablen
+------------------------------------------------
+
+Einige Variablen, die in Dokumentenvorlagen verwendet werden, mussten
+aufgrund von Namenskonflikten umbenannt werden. Dazu gehören:
+
+* Adress- und Kontaktinformationen des angemeldeten Mitarbeiters. Die
+  Variablen "company", "address" und "businessnumber" haben alle einen
+  Präfix "employee_" bekommen und heißen nun "employee_company",
+  "employee_address" und "employee_businessnumber".
+
+Zu beachten ist außerdem, dass der Befehl <%include ...%> in
+Dokumentenvorlagen nicht mehr zur Verfügung steht.
 
 ####################################\r
 # Veraenderungen von Lx-Office ERP #\r
 ####################################\r
+2007-01-19 - Version 2.4.1\r
+  - CSV-Import auf Verwendung von Buchungsgruppen angepasst\r
+  - Bei Einkaufs- und Verkaufsmasken lassen sich die zweiten Positionszeilen\r
+    verstecken und wieder anzeigen\r
+  - PDFs für die USTVA 2007 hinzugefügt\r
+  - Email-Funktion: Wenn bei den Kundendaten keine Emailadresse angegeben,\r
+    dafür aber ein Ansprechpartner ausgewählt ist, dann wird die Emailadresse\r
+    des Ansprechpartners automatisch eingetragen.\r
+  - Skontobeträge wurden fälschlicherweise vom Nettobetrag berechnet\r
+  - Neues, auf CSS basierendes Menü\r
+  - Bei allen Datumsfeldern den Javascript-Kalender hinzugefügt und an einigen\r
+    Stellen die Beschriftung berichtigt\r
+  - Fehler beim Buchen. Wenn EUR gesetzt war, wurde bei Eingangsrechnungen\r
+    das Bestandskonto angesprochen. Wenn EUR nicht gesetzt war, wurden beim\r
+    Verkauf die Kosten nicht vom Bestands- auf Kostenkonto umgebucht\r
+  - Beim Aufrufen der Masken für Dialogbuchen, Debitoren- und\r
+    Kreditorenrechnungen wird Datum der letzten Buchung als Datum für die\r
+    neue Maske ausgewählt\r
+  - Das Feld "Zahlungsziel" wurde aus den Masken entfernt\r
+  - Beim Anlegen von Buchungsgruppen werden die in den Benutzereinstelungen\r
+    festgelegten Standardkonten vorselektiert\r
+  - Beim DATEV-Export werden die Dateien nicht mehr auf dem Server abgelegt\r
+    sondern dem Benutzer direkt zum Download angeboten\r
+  - Die Bearbeitungsmöglichkeiten für Vorlagen wurden aus dem Menü entfern\r
+  - Verschiedene Konten und Buchungsgruppen wurden von "...16%..." auf\r
+    "...16%/19%..." umbenannt\r
+  - Anzeigefehler im Buchungsjournal: Wenn eine Buchung aufgerufen wird,\r
+    so werden jetzt die richtigen Konten in den Drop-Down-Listen ausgewählt\r
+  - Bei Einkaufsmasken wird der Einkaufs- und nicht der Verkaufspreis\r
+    vorbelegt\r
+  - Jeder Benutzer kann das standardmäßig vorausgewählte Vorlagenformat\r
+    festlegen\r
+  - Falsche Bestimmung des Steuersatzes bei Gutschriften behoben\r
+  - In den Vorlagen stehen diverse neue Variablen zur Verfügung\r
+  - Bei Eingangsrechnungen wird der richtige Nummernkreis verwendet\r
+  - Steuerzonen können überall auch nachträglich geändert werden\r
+  - Das Fälligkeitsdatum wird automatisch anhand der Zahlungsbedingungen\r
+    gesetzt\r
+  - $latex_templates und $latex werden nun beide akzeptiert und aktivieren\r
+    beide die Unterstützung von LaTeX-Vorlagen\r
+  - Falsche Steuerschlüsselangaben in Dantebanken behoben\r
+  - Fehler in den Kontenrahmendefinitionen für SKR03 und SKR04 behoben\r
+  - Aktualisierung der Dokumentation bzgl. Vorlagenvariablen und der\r
+    Verwendung von OpenDocument-Vorlagen\r
+  - Ersetzen der Einheitennamen anhand der Vorlagensprache\r
+  - Umformartierungen von Zahlen und Datumgsangaben anhand der\r
+    Vorlagensprache\r
+  - Bugfix 507 - interne Bemerkungen werden zu öffentlichen Bemerkungen\r
+  - Bugfix 502 - Keine PDF USTVA Vordrucke für 2007 vorhanden\r
+  - Bugfix 500, 503 - p_discount verrutscht in der Zeile bei "Waren gruppiert"\r
+  - Bugfix 499 - Ustva Export in Winston funktioniert nicht LX-Office 2.4.0.3\r
+  - Bugfix 497 - Einkaufsrechnung lässt sich nicht stornieren\r
+  - Bugfix 495 - SQL-Fehler beim Löschen von Eiheiten\r
+  - Bugfix 494 - SQL-Fehler beim Eintragen von Dienstleistungseinheiten\r
+  - Bugfix 491 - Neue Ware erfassen umständlich\r
+  - Bugfix 484 - Newlines in der Firmenadresse und Berichte\r
+  - Bugfix 478 - Konten in Dialogbuchung werden nach Buchung nicht mehr\r
+    angezeigt\r
+  - Bugfix 476 - Umwandlung Kundenauftrag in Lieferantenauftrag: fehlerhafte\r
+    Zahlenformatierung\r
+  - Bugfix 475 - Bei Einkaufsmasken wird der falsche Standardpreis verwendet\r
+  - Bugfix 474 - Version 2.4.0: Kodierfehler in SL/IC.pm\r
+  - Bugfix 470 - Fehler nach update auf 2.4.0, alte Rechnungen anzeigen\r
+  - Bugfix 469 - Fehler bei Zahlungskonditionen erfassen\r
+  - Bugfix 468 - Unternehmer-Steuernummer steht nicht als Variable in\r
+    Latextemplates zur Verfügung\r
+  - Bugfix 466 - Templatevariable "ustid" wird nicht gefüllt\r
+  - Bugfix 465 - Internal Server Error bei Steuerfreien Rechnungen\r
+  - Bugfix 464 - Steuerzone ändern\r
+  - Bugfix 460 - Bei Wareneinkauf wird in der Rechnung der Verkaufspreis\r
+    gebucht\r
+  - Bugfix 449 - Variablen in Vorlagen\r
+  - Bugfix 442 - EUST wird in Winston-Export nicht berücksichtigt\r
+  - Bugfixes 400, 401, 479, 492, 493 - Diverse Rechtschreibfehler\r
+  - Bugfix 359 - Noch eine unklare Betitelung - Nur eine Kleinigkeit\r
+  - Bugfix 352 - Zahlungsziel in Auftrag und Angebot\r
+  - Bugfix 345 - Datevexport nur mit LXDEBUG<>0\r
+  - Bugfix 309 - Konten anlegen und pflegen: Kontoart nicht ausreichend\r
+    auswählbar\r
+  - Bugfix 294 - Server Error bei Datev-Export\r
+  - Bugfix 291 - Wandeln von Angeboten/Anfragen verlieren Nachkommawerte\r
+  - Bugfix 151 - (Admin) Datenbank-Vorlage wird ignoriert\r
+\r
 2006-12-12 - Version 2.4.0\r
   - USTVA jetzt mit Taxbird und Winston Anbindung (als Templates verfügbar)\r
   - Neues Steuersystem für beliebig viele Steuersätze pro Konto\r
 
     Blöcke, bedingte Anweisungen und Schleifen</a>
 
    <ol>
-    <li><a href="dokumentenvorlagen-und-variablen.html#bloecke_einschr_latex">
-      Einschänkungen für Blöcke in LaTeX-Vorlagen</a></li>
-
-    <li><a href="dokumentenvorlagen-und-variablen.html#bloecke_einschr_opendocument">
-      Einschänkungen für Blöcke in OpenDocument-Vorlagen</a></li>
-
-    <li><a href="dokumentenvorlagen-und-variablen.html#bloecke_include">
-      Die <code>include</code>-Anweisung</a></li>
-
     <li><a href="dokumentenvorlagen-und-variablen.html#bloecke_ifnot">
       Der <code>if not</code>-Block</a></li>
 
     <td><code>name</code></td>
     <td>Firmenname</td>
    </tr>
+   <tr>
+    <td><code>payment_terms</code></td>
+    <td>Zahlungskonditionen</td>
+   </tr>
    <tr>
     <td><code>phone</code></td>
     <td>Telefonnummer</td>
     <td>Land (Lieferadresse)
      <a href="dokumentenvorlagen-und-variablen.html#anmerkung_shipto">*</a></td>
    </tr>
+   <tr>
+    <td><code>shiptodepartment1</code></td>
+    <td>Abteilung 1 (Lieferadresse)
+     <a href="dokumentenvorlagen-und-variablen.html#anmerkung_shipto">*</a></td>
+   </tr>
+   <tr>
+    <td><code>shiptodepartment2</code></td>
+    <td>Abteilung 2 (Lieferadresse)
+     <a href="dokumentenvorlagen-und-variablen.html#anmerkung_shipto">*</a></td>
+   </tr>
    <tr>
     <td><code>shiptoemail</code></td>
     <td>Email (Lieferadresse)
     <td><code>taxnumber</code></td>
     <td>Steuernummer</td>
    </tr>
-   <tr>
-    <td><code>terms</code></td>
-    <td>Zahlungsziel</td>
-   </tr>
    <tr>
     <td><code>vendoremail</code></td>
     <td>Email des Lieferanten; nur für Lieferanten</td>
  <p>
   <table border="1">
    <tr><th>Variablenname</th><th>Bedeutung</th></tr>
+   <tr>
+    <td><code>employee_address</code></td>
+    <td>Adressfeld</td>
+   </tr>
+   <tr>
+    <td><code>employee_businessnumber</code></td>
+    <td>Firmennummer</td>
+   </tr>
+   <tr>
+    <td><code>employee_company</code></td>
+    <td>Firmenname</td>
+   </tr>
+   <tr>
+    <td><code>employee_co_ustid</code></td>
+    <td>Usatzsteuer-Identifikationsnummer</td>
+   </tr>
+   <tr>
+    <td><code>employee_duns</code></td>
+    <td>DUNS-Nummer</td>
+   </tr>
    <tr>
     <td><code>employee_email</code></td>
     <td>Email</td>
     <td><code>employee_signature</code></td>
     <td>Signatur</td>
    </tr>
+   <tr>
+    <td><code>employee_taxnumber</code></td>
+    <td>Steuernummer</td>
+   </tr>
    <tr>
     <td><code>employee_tel</code></td>
     <td>Telefonnummer</td>
     <td><code>ordnumber</code></td>
     <td>Auftragsnummer, wenn die Rechnung aus einem Auftrag erstellt wurde</td>
    </tr>
+   <tr>
+    <td><code>payment_terms</code></td>
+    <td>Zahlungskonditionen</td>
+   </tr>
    <tr>
     <td><code>quonumber</code></td>
     <td>Angebotsnummer</td>
   gesondert behandelt werden. Diese sind wie Variablennamen in spezieller
   Weise markiert: <code><%anweisung%></code></p>
 
- <h3><a name="bloecke_einschr_latex">
-   Einschänkungen für Blöcke in LaTeX-Vorlagen</a></h3>
-
- <p>Achtung: Blöcke können in LaTeX-Vorlagen momentan nicht
-   verschachtelt werden. Das bedeutet, dass innerhalb einer
-   <code><%foreach%></code>-Schleife keine
-   <code><%if%></code>-Abfragen verwendet werden können. Dieses
-   kann man aber mit LaTeX-Bordmitteln selber nachgebildet werden. Dazu muss
-   im Vorspann das Paket <code>ifthen</code> eingebunden werden. Das Konstrukt
-   selber sieht dann wie folgt aus:</p>
-
- <p class="blue"><code>\ifthenelse{\equal{<%variable%>}{}}{}{Dieser
-   Text erscheint nur, wenn <%variable%> nicht leer ist.}</code></p>
-
- <h3><a name="bloecke_einschr_opendocument">
-   Einschänkungen für Blöcke in OpenDocument-Vorlagen</a></h3>
-
- <p>Die eben erwähnten Einschränkungen für
-  LaTeX-Vorlagen gelten in abgeschwächter Form auch für
-  OpenDocument-Vorlagen. Auch bei OpenDocument-Vorlagen können
-  Blöcke nicht verschachtelt werden. Einzige Ausnahme ist, dass
-  <code><if></code> und
-  <code><ifnot></code>-Blöcke innerhalb von
-  <code><foreach></code>-Blöcken auftreten
-  dürfen.</p>
-
- <h3><a name="bloecke_include">Die <code>include</code>-Anweisung</a></h3>
-
- <p class="blue"><code><%include dateiname.ext%></code></p>
-
- <p>Dieser Block funktioniert nur in LaTeX- und HTML-Vorlagen.</p>
-
- <p>Fügt den Inhalt einer Datei an der entsprechenden Stelle ein. Der
-  eingefügte Text wird ganz normal durch den Parser behandelt und kann
-  Variablen und Blöcke enthalten.</p>
-
  <h3><a name="bloecke_ifnot">Der <code>if not</code>-Block</a></h3>
 
  <p class="blue"><code><%if not variablenname%><br>
    ...<br>
-   <%end if></code></p>
+   <%end></code></p>
 
  <p>Eine normale "if-not-then"-Bedingung. Die Zeilen zwischen dem "if not" und
   dem "end" werden nur ausgegeben, wenn die Variable "variablenname" nicht
 
  <p class="blue"><code><%if variablenname%><br>
    ...<br>
-   <%end if></code></p>
+   <%end></code></p>
 
  <p>Eine normale "if-then"-Bedingung. Die Zeilen zwischen dem "if" und dem
   "end" werden nur ausgegeben, wenn die Variable "variablenname" gesetzt und
 
  <p class="blue"><code><%foreach variablenname%><br>
    ...<br>
-   <%end foreach></code></p>
+   <%end></code></p>
 
  <p>Fügt die Zeilen zwischen den beiden Anweisungen so oft ein, wie das
   Perl-Array der Variablen "variablenname" Elemente enthät. Dieses
    Artikelnummer: <%number%><br>
    Beschreibung: <%description%><br>
    ...<br>
-   <%end foreach></code></p>
+   <%end></code></p>
 
  <p>Besonderheit in OpenDocument-Vorlagen: Tritt ein
-  <code><foreach></code>-Blcok innerhalb einer Tabellenzelle
+  <code><foreach></code>-Block innerhalb einer Tabellenzelle
   auf, so wird die komplette Tabellenzeile so oft wiederholt wie
   notwendig. Tritt er außerhalb auf, so wird nur der Inhalt
-  zwischen <code><foreach></code> und <code><end
-  foreach></code> wiederholt, nicht aber die komplette Zeile, in
-  der er steht.</p>
+  zwischen <code><foreach></code> und <code><end></code>
+  wiederholt, nicht aber die komplette Zeile, in der er steht.</p>
 
  <h3><a name="bloecke_pagebreak">Der <code>pagebreak</code>-Block</a></h3>
 
  <p class="blue"><code><%pagebreak ZpZ ZeS ZzS%><br>
    ...<br>
-   <%end pagebreak%></code></p>
+   <%end></code></p>
 
  <p>Dieser Block existiert nur in LaTeX-Vorlagen.</p>
 
 
--- /dev/null
+Neuer Mechanismus für SQL-Upgradedateien
+----------------------------------------
+
+Der alte Mechanismus für SQL-Upgradescripte, der auf einer
+Versionsnummer beruht und dann in sql/Pg-upgrade nach einem Script für
+diese Versionsnummer sucht, schränkt sehr ein, z.B. was die parallele
+Entwicklung im stable- und unstable-Baum betrifft.
+
+Dieser Mechanismus wurde für Lx-Office 2.4.1 deutlich erweitert. Es
+werden weiterhin alle Scripte aus sql/Pg-upgrade
+ausgeführt. Zusätzlich gibt es aber ein zweites Verzeichnis,
+sql/Pg-upgrade2. In diesem Verzeichnis muss pro Datenbankupgrade eine
+Datei existieren, die neben den eigentlich auszuführenden SQL- oder
+Perl-Befehlen einige Kontrollinformationen enthält.
+
+Neu sind die Kontrollinformationen, die Abhängigkeiten und Prioritäten
+definieren können werden, sodass Datenbankscripte zwar in einer
+sicheren Reihenfolge ausgeführt werden (z.B. darf ein "ALTER TABLE"
+erst ausgeführt werden, wenn die Tabelle mit "CREATE TABLE" angelegt
+wurde), diese Reihenfolge aber so flexibel ist, dass man keine
+Versionsnummern mehr braucht.
+
+Lx-Office merkt sich dabei, welches der Upgradescripte in
+sql/Pg-upgrade2 bereits durchgeführt wurde und führt diese nicht
+erneut aus. Dazu dient die Tabelle "schema_info", die bei der
+Anmeldung automatisch angelegt wird.
+
+Format der Kontrollinformationen
+--------------------------------
+
+Die Kontrollinformationen sollten sich am Anfang der jeweiligen
+Upgradedatei befinden. Jede Zeile, die Kontrollinformationen enthält,
+hat dabei das folgende Format:
+
+Für SQL-Upgradedateien:
+
+-- @key: value
+
+
+Für Perl-Upgradedateien:
+
+# @key: value
+
+
+Leerzeichen vor "value" werden entfern.
+
+Die folgenden Schlüsselworte werden verarbeitet:
+
+* tag: Wird zwingend benötigt. Dies ist der "Name" des
+  Upgrades. Dieser "tag" kann von anderen Kontrolldateien in ihren
+  Abhängigkeiten verwendet werden (Schlüsselwort "depends"). Der "tag"
+  ist auch der Name, der in der Datenbank eingetragen wird.
+
+  Normalerweise sollte die Kontrolldatei genau so heißen wie der
+  "tag", nur mit der Endung ".sql" bzw. "pl".
+
+  Ein Tag darf nur aus alphanumerischen Zeichen sowie den Zeichen _ -
+  ( ) bestehen. Insbesondere sind Leerzeichen nicht erlaubt und
+  sollten stattdessen mit Unterstrichen ersetzt werden.
+
+* description: Benötigt. Eine Beschreibung, was in diesem Update
+  passiert. Diese wird dem Benutzer beim eigentlichen Datenbankupdate
+  angezeigt. Während der Tag in englisch gehalten sein sollte, sollte
+  die Beschreibung auf Deutsch erfolgen.
+
+* depends: Optional. Eine mit Leerzeichen getrennte Liste von "tags",
+  von denen dieses Upgradescript abhängt. Lx-Office stellt sicher,
+  dass die in dieser Liste aufgeführten Scripte bereits durchgeführt
+  wurden, bevor dieses Script ausgeführt wird.
+
+  Abhängigkeiten werden rekursiv betrachtet. Wenn also ein Script "b"
+  existiert, das von Änderungen in "a" abhängt, und eine neue
+  Kontrolldatei für "c" erstellt wird, die von Änderungen in "a" und
+  "b" abhängt, so genügt es, in "c" nur den Tag "b" als Abhängigkeit
+  zu definieren.
+
+  Es ist nicht erlaubt, sich selbst referenzierende Abhängigkeiten zu
+  definieren (z.B. "a" -> "b", "b" -> "c" und "c" -> "a").
+
+* priority: Optional. Ein Zahlenwert, der die Reihenfolge bestimmt, in
+  der Scripte ausgeführt werden, die die gleichen Abhängigkeitstiefen
+  besitzen. Fehlt dieser Parameter, so wird der Wert 1000 benutzt.
+
+  Dies ist reine Kosmetik. Für echte Reihenfolgen muss "depends"
+  benutzt werden. Lx-Office sortiert die auszuführenden Scripte zuerst
+  nach der Abhängigkeitstiefe (wenn "z" von "y" abhängt und "y" von
+  "x", so hat "z" eine Abhängigkeitstiefe von 2, "y" von 1 und "x" von
+  0. "x" würde hier zuerst ausgeführt, dann "y", dann "z"), dann nach
+  der Priorität und bei gleicher Priorität alphabetisch nach dem
+  "tag".
+
+Hilfsscript dbupgrade2_tool.pl
+------------------------------
+
+Um die Arbeit mit den Abhängigkeiten etwas zu erleichtern, existiert
+ein Hilfsscript namens "scripts/dbupgrade2_tool.pl". Es muss aus dem
+Lx-Office-ERP-Basisverzeichnis heraus aufgerufen werden. Dieses Tool
+liest alle Datenbankupgradescripte aus dem Verzeichnis sql/Pg-upgrade2
+aus. Es benutzt dafür die gleichen Methoden wie Lx-Office selber,
+sodass alle Fehlersituationen von der Kommandozeile überprüft werden
+können.
+
+Wird dem Script kein weiterer Parameter übergeben, so wird nur eine
+Überprüfung der Felder und Abhängigkeiten vorgenommen. Man kann sich
+aber auch Informationen auf verschiedene Art ausgeben lassen:
+
+1. Listenform: "./scripts/dbupgrade2_tool.pl --list"
+
+   Gibt eine Liste aller Scripte aus. Die Liste ist in der Reihenfolge
+   sortiert, in der Lx-Office die Scripte ausführen würde. Es werden
+   neben der Listenposition der Tag, die Abhängigkeitstiefe und die
+   Priorität ausgegeben.
+
+2. Baumform: "./scripts/dbupgrade2_tool.pl --tree"
+
+   Listet alle Tags in Baumform basierend auf den Abhängigkeiten
+   auf. Die "Wurzelknoten" sind dabei die Scripte, von denen keine
+   anderen abhängen. Die Unterknoten sind Scripte, die beim
+   übergeordneten Script als Abhängigkeit eingetragen sind.
+
+3. Umgekehrte Baumform: "./scripts/dbupgrade2_tool.pl --rtree"
+
+   Listet alle Tags in Baumform basierend auf den Abhängigkeiten auf.
+   Die "Wurzelknoten" sind dabei die Scripte mit der geringsten
+   Abhängigkeitstiefe. Die Unterknoten sind Scripte, die das
+   übergeordnete Script als Abhängigkeit eingetragen haben.
+
+4. Baumform mit Postscriptausgabe: "./scripts/dbupgrade2_tool.pl --graphviz"
+
+   Benötigt das Tool "graphviz", um mit seiner Hilfe die Baumform aus
+   3. in eine Postscriptdatei namens "db_dependencies.ps"
+   auszugeben. Dies ist vermutlich die übersichtlichste Form, weil
+   hierbei jeder Knoten nur einmal ausgegeben wird. Bei den
+   Textmodusbaumformen hingegen können Knoten und all ihre
+   Abhängigkeiten mehrfach ausgegeben werden.
+
+5. Scripte, von denen kein anderes Script abhängt:
+   "./scripts/dbupgrade2_tool.pl --nodeps"
+
+   Listet die Tags aller Scripte auf, von denen keine anderen Scripte
+   abhängen.
+
 
--- /dev/null
+function show_form_details(new_value) {
+  document.forms[0].show_details.value = new_value;
+  document.getElementById("update_button").click();
+}
 
 };
 
 $self->{subs} = {
+  'get_base_unit'               => 'get_base_unit',
   'mydberror'                   => 'mydberror',
   'myshowerror'                 => 'myshowerror',
+  'retrieve_units'              => 'retrieve_units',
+  'unit_select_data'            => 'unit_select_data',
   'update_units'                => 'update_units',
   'update_units_add_unit'       => 'update_units_add_unit',
   'update_units_assign_known'   => 'update_units_assign_known',
 
   'Date Format'                 => 'Datumsformat',
   'Delete'                      => 'Löschen',
   'Delete Dataset'              => 'Datenbank löschen',
+  'Dependency loop detected:'   => 'Schleife in den Abhängigkeiten entdeckt:',
   'Directory'                   => 'Verzeichnis',
   'Driver'                      => 'Treiber',
   'Dropdown Limit'              => 'Auswahllistenbegrenzung',
   'E-mail'                      => 'eMail',
   'Edit User'                   => 'Benutzerdaten bearbeiten',
+  'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
   'Existing Datasets'           => 'existierende Datenbanken',
   'Fax'                         => 'Fax',
   'File locked!'                => 'Datei gesperrt!',
   'Login'                       => 'Anmeldung',
   'Login name missing!'         => 'Loginname fehlt.',
   'Manager'                     => 'Manager',
+  'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
+  'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
+  'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Multibyte Encoding'          => 'Schriftsatz',
   'Name'                        => 'Name',
   'New Templates'               => 'neue Vorlagen',
   'No Dataset selected!'        => 'Keine Datenbank ausgewählt!',
   'Nothing to delete!'          => 'Es konnte nichts gelöscht werden!',
   'Number Format'               => 'Zahlenformat',
+  'Old (on the side)'           => 'Alt (seitlich)',
   'Oracle Database Administration' => 'Oracle Datenbankadministration',
   'Password'                    => 'Passwort',
   'Password changed!'           => 'Passwort geändert!',
   'Setup Menu'                  => 'Menüsetup',
   'Setup Templates'             => 'Vorlagen auswählen',
   'Signature'                   => 'Unterschrift',
-  'Steuernummer'                => 'Steuernummer',
   'Stylesheet'                  => 'Stilvorlage',
   'Supervisor'                  => 'Supervisor',
+  'Tax number'                  => 'Steuernummer',
   'Templates'                   => 'Vorlagen',
+  'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.',
   'The following Datasets are not in use and can be deleted' => 'Die folgenden Datenbanken sind nicht in Verwendung und können gelöscht werden',
   'The following Datasets need to be updated' => 'Folgende Datenbanken müssen aktualisiert werden',
   'The passwords do not match.' => 'Die Passwörter stimmen nicht überein.',
   'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'In diesem Schritt werden bestehende Datenbanken gesucht. Es werden noch keine Änderungen vorgenommen!',
   'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Um einer Gruppe einen neuen Benutzer hinzuzufügen, ändern und speichern Sie am einfachsten einen bestehen den Zugriffsnamen. Unter dem neuen Namen wird dann ein Benutzer mit denselben Einstellungen angelegt.',
+  'Top (CSS)'                   => 'Oben (mit CSS)',
+  'Top (Javascript)'            => 'Oben (mit Javascript)',
+  'Unknown dependency \'%s\'.'  => 'Unbekannte Abhängigkeit \'%s\'.',
   'Unlock System'               => 'System entsperren',
   'Update Dataset'              => 'Datenbank aktualisieren',
   'Use Templates'               => 'benutze Vorlagen',
 
   'Account'                     => 'Konto',
   'Account Number'              => 'Kontonummer',
   'Account Number missing!'     => 'Kontonummer fehlt!',
+  'Account Nummer'              => 'Kontonummer',
   'Account Type'                => 'Kontoart',
   'Account Type missing!'       => 'Kontoart fehlt!',
   'Account deleted!'            => 'Konto gelöscht!',
   'All Accounts'                => 'Alle Konten',
   'All Datasets up to date!'    => 'Alle Datenbanken sind auf aktuellem Stand.',
   'All changes in that file have been reverted.' => 'Alle Änderungen in dieser Datei wurden rückgängig gemacht.',
+  'Amended Advance Turnover Tax Return' => 'Berichtigte Anmeldung',
+  'Amended Advance Turnover Tax Return (Nr. 10)' => 'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)',
   'Amount'                      => 'Betrag',
   'Amount Due'                  => 'Betrag fällig',
-  'Angaben zum Finanzamt'       => 'Angaben zum Finanzamt',
   'Ansprechpartner'             => '',
-  'Application Error. No Format given!' => 'Fehler in der Anwendung. Das Format fehlt.',
-  'Application Error. Wrong Format: ' => 'Fehler in der Anwendung. Falsches Format: ',
+  'Application Error. No Format given' => 'Fehler in der Anwendung. Das Ausgabeformat fehlt.',
+  'Application Error. Wrong Format' => 'Fehler in der Anwendung. Falsches Format: ',
+  'Applying <TMPL_VAR file ESCAPE=HTML>:' => 'Führe <TMPL_VAR file ESCAPE=HTML> aus:',
   'Apr'                         => 'Apr',
   'April'                       => 'April',
   'Are you sure you want to delete Invoice Number' => 'Soll die Rechnung mit folgender Nummer wirklich gelöscht werden:',
   'Asset'                       => 'Aktiva/Mittelverwendung',
   'Assign new units'            => 'Neue Einheiten zuweisen',
   'Assign units'                => 'Einheiten zuweisen',
+  'Assume Tax Consultant Data in Tax Computation?' => 'Beraterdaten in UStVA übernehmen?',
   'Attach PDF:'                 => 'PDF anhängen',
   'Attachment'                  => 'als Anhang',
   'Audit Control'               => 'Bücherkontrolle',
   'Aufwand Inland'              => '',
   'Aug'                         => 'Aug',
   'August'                      => 'August',
-  'Ausgabeformat'               => 'Ausgabeformat',
-  'Ausgabeformat auswählen...'  => 'Ausgabeformat auswählen...',
   'Auto Send?'                  => 'Auto. Versand?',
   'BG anzeigen'                 => 'BG anzeigen',
   'BG hinzufügen'               => 'BG hinzufügen',
-  'BLZ: '                       => 'BLZ: ',
   'BOM'                         => 'Stückliste',
   'BWA'                         => 'BWA',
   'Back'                        => 'Zurück',
-  'Back to user config...'      => 'Benutzereinstellungen',
   'Backup sent to'              => 'Eine Sicherungskopie wurde gesandt an',
   'Balance'                     => 'Bilanz',
   'Balance Sheet'               => 'Bilanz',
   'Bank'                        => 'Bank',
+  'Bank Code'                   => 'BLZ: ',
+  'Bank Code (long)'            => 'Bankleitzahl (BLZ)',
   'Bank Code Number'            => 'Bankleitzahl',
-  'Bankleitzahl'                => 'Bankleitzahl',
-  'Bankleitzahl (BLZ)'          => 'Bankleitzahl (BLZ)',
-  'Bankverbindung'              => 'Bankverbindung',
-  'Bankverbindung des Finanzamts' => 'Bankverbindung des Finanzamts',
-  'Bankverbindungen'            => 'Bankverbindungen',
-  'Bankverbindungen des Finanzamts' => 'Bankverbindungen des Finanzamts',
+  'Bank Connection'             => 'Bankverbindung',
+  'Bank Connection Tax Office'  => 'Bankverbindung des Finanzamts',
   'Base unit'                   => 'Basiseinheit',
   'Batch Printing'              => 'Druck',
   'Bcc'                         => 'Bcc',
   'Belegnummer'                 => 'Buchungsnummer',
-  'Beraterdaten in UStVA übernehmen?' => 'Beraterdaten in UStVA übernehmen?',
   'Beratername'                 => 'Beratername',
   'Beraternummer'               => 'Beraternummer',
-  'Berichtigte Anmeldung'       => 'Berichtigte Anmeldung',
   'Bestandskonto'               => '',
   'Bilanz'                      => 'Bilanz',
   'Billing Address'             => 'Rechnungsadresse',
   'Birthday'                    => 'Geburtstag',
   'Bis'                         => 'bis',
   'Bis Konto: '                 => 'bis Konto: ',
-  'Bitte Angaben überprüfen'    => 'Bitte Angaben überprüfen',
-  'Bitte alle Angaben überprüfen' => 'Bitte alle Angaben überprüfen',
-  'Bitte eine Steuernummer angeben' => 'Bitte eine Steuernummer angeben',
   'Body:'                       => 'Text:',
   'Books are open'              => 'Die Bücher sind geöffnet.',
   'Bought'                      => 'Gekauft',
   'Character Set'               => 'Zeichensatz',
   'Chart of Accounts'           => 'Kontenübersicht',
   'Chart of accounts'           => 'Kontenrahmen',
-  'Check'                       => 'Scheck',
+  'Check Details'               => 'Bitte Angaben überprüfen',
   'Checks'                      => 'Schecks',
   'Choose Customer'             => 'Endkunde wählen:',
+  'Choose Outputformat'         => 'Ausgabeformat auswählen...',
   'Choose Vendor'               => 'Händler wählen',
+  'Choose a Tax Number'         => 'Bitte eine Steuernummer angeben',
   'City'                        => 'Stadt',
   'Cleared Balance'             => 'abgeschlossen',
+  'Clearing Tax Received (No 71)' => 'Verrechnung des Erstattungsbetrages erwünscht (Zeile 71)',
   'Click on login name to edit!' => 'Zum Bearbeiten den Zugriffsnamen anklicken!',
   'Close'                       => 'Übernehmen',
   'Close Books up to'           => 'Die Bücher abschließen bis zum',
   'Copies'                      => 'Kopien',
   'Copy to COA'                 => 'In Kontenplan kopieren',
   'Cost Center'                 => 'Kostenstelle',
+  'Costs'                       => 'Kosten',
   'Could not copy %s to %s. Reason: %s' => 'Die Datei "%s" konnte nicht nach "%s" kopiert werden. Grund: %s',
   'Could not open the file users/members.' => 'Die Datei "users/members" konnte nicht geöffnet werden.',
   'Could not rename %s to %s. Reason: %s' => 'Die Datei "%s" konnte nicht in "%s" umbenannt werden. Grund: %s',
   'Credit Note Number'          => 'Gutschriftnummer',
   'Credit Tax'                  => 'Umsatzsteuer',
   'Credit Tax Account'          => 'Umsatzsteuerkonto',
+  'Credit note (one letter abbreviation)' => 'G',
   'Curr'                        => 'Währung',
   'Currency'                    => 'Währung',
   'Current'                     => 'Betrag',
   'Date received missing!'      => 'Empfangsdatum fehlt!',
   'Datenträgernummer'           => 'Datenträgernummer',
   'Datum von'                   => 'Datum von',
-  'Dauerfristverlängerung'      => 'Dauerfristverlängerung',
   'Debit'                       => 'Soll',
   'Debit Account'               => 'Sollkonto',
   'Debit Tax'                   => 'Vorsteuer',
   'December'                    => 'Dezember',
   'Decimalplaces'               => 'Dezimalstellen',
   'Decrease'                    => 'Verringern',
+  'Default template format'     => 'Standardvorlagenformat',
   'Delete'                      => 'Löschen',
   'Delete Account'              => 'Konto löschen',
   'Delete Dataset'              => 'Datenbank löschen',
   'Department deleted!'         => 'Abteilung gelöscht.',
   'Department saved!'           => 'Abteilung gespeichert.',
   'Departments'                 => 'Abteilungen',
+  'Dependency loop detected:'   => 'Schleife in den Abhängigkeiten entdeckt:',
   'Deposit'                     => 'Gutschrift',
   'Description'                 => 'Beschreibung',
   'Description missing!'        => 'Beschreibung fehlt.',
   'Dunnings'                    => 'Mahnungen',
   'E-mail'                      => 'eMail',
   'E-mail Statement to'         => 'Fälligkeitsabrechnung als eMail an',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
-  'ELSTER Export nach Taxbird'  => 'ELSTER-Export nach Taxbird',
+  'ELSTER Export (Taxbird)'     => 'ELSTER-Export nach Taxbird',
+  'ELSTER Export (Winston)'     => 'ELSTER Export nach Winston',
   'ELSTER Export nach Winston'  => 'ELSTER Export nach Winston',
-  'ELSTER-Steuernummer: '       => 'ELSTER-Steuernummer: ',
+  'ELSTER Tax Number'           => 'ELSTER-Steuernummer: ',
   'EU with VAT ID'              => 'EU mit UstId-Nummer',
   'EU without VAT ID'           => 'EU ohne UstId-Nummer',
   'EUER'                        => 'Einnahmen-/Überschussrechnung',
   'Erlöse EU o. UStId'          => 'Erlöse EU o. UStId',
   'Erlöse Inland'               => 'Erlöse Inland',
   'Error'                       => 'Fehler',
+  'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
   'Error!'                      => 'Fehler!',
   'Exch'                        => 'Wechselkurs.',
   'Exchangerate'                => 'Wechselkurs',
   'Export Buchungsdaten'        => 'Export Buchungsdaten',
   'Export Stammdaten'           => 'Export Stammdaten',
   'Extended'                    => 'Gesamt',
+  'Extension Of Time'           => 'Dauerfristverlängerung',
   'Factor'                      => 'Faktor',
   'Fax'                         => 'Fax',
-  'Fax. : '                     => 'Fax. : ',
-  'Fax.: '                      => 'Fax.: ',
   'Feb'                         => 'Feb',
   'February'                    => 'Februar',
   'Fee'                         => 'Gebühr',
   'File locked!'                => 'Datei gesperrt!',
-  'Finanzamt'                   => 'Finanzamt',
-  'Finanzamt - Einstellungen'   => 'Finanzamt - Einstellungen',
-  'Firma'                       => 'Firma',
   'Folgekonto'                  => 'Folgekonto',
   'For each unit there\'s either no or exactly one base unit. If you chose a base unit then you also have to chose a factor. That way the new unit will be defined as a multiple of the base unit. The base unit must be the "smaller" one. A factor may not be less than 1. Therefore you may define "kg" with the base unit "g" and a factor of "1", but not the other way round.' => 'Einheiten haben entweder keine oder genau eine Basiseinheit, von der sie ein Vielfaches sind. Wenn Sie eine Basiseinheit auswählen, dann müssen Sie auch einen Faktor eingeben. Sie müssen Einheiten als ein Vielfaches einer kleineren Einheit eingeben. So ist die Definition von "kg" mit der Basiseinheit "g" und dem Faktor 1000 zulässig, die Definition von "g" mit der Basiseinheit "kg" und dem Faktor "0,001" hingegen nicht.',
   'Foreign Exchange Gain'       => 'Wechselkurserträge',
   'Foreign Exchange Loss'       => 'Wechselkursaufwendungen',
+  'Form details (second row)'   => 'Formulardetails (zweite Positionszeile)',
   'Formula'                     => 'Formel',
   'Free report period'          => 'Freier Zeitraum',
   'Fristsetzung'                => 'Fristsetzung',
   'Groups'                      => 'Warengruppen',
   'Gültig ab'                   => 'Gültig ab',
   'HTML'                        => 'HTML',
-  'HTML Templates'              => 'HTML-Vorlagen',
   'Heading'                     => 'Überschrift',
   'Help'                        => 'Hilfe',
-  'Help:'                       => 'Hilfe:',
+  'Hide by default'             => 'Standardmäßig verstecken',
   'Hint-Missing-Preferences'    => 'Bitte fehlende USTVA Einstellungen ergänzen (Menüpunkt: Programm)',
-  'Hinweise'                    => 'Hinweise',
+  'Hints'                       => 'Hinweise',
   'Homepage'                    => 'Homepage',
   'Host'                        => 'Datenbankcomputer',
   'Hostname missing!'           => 'Computername fehlt!',
   'If you see this message, you most likely just setup your LX-Office and haven\'t added any entry types. If this is the case, the option is accessible for administrators in the System menu.' => 'Wenn Sie diese Meldung sehen haben Sie wahrscheinlich ein frisches LX-Office Setup und noch keine Buchungsgruppen eingerichtet. Ein Administrator kann dies im Systemmenü erledigen.',
   'Image'                       => 'Grafik',
   'Import CSV'                  => '',
-  'Impossible to create yearly Tax Report as PDF or Postscript<br \> Not yet implemented!' => 'Es ist noch nicht möglich, die Umsatzsteuervoranmeldung für das ganze Jahr als PDF oder Postscript auszugeben. Noch nicht implementiert.',
-  'Impossible to create yearly Tax Report via Winston or Taxbird.<br \> Not yet implemented!' => 'Es ist noch nicht möglich, die Umsatzsteuervoranmeldung für das ganze Jahr für Winston oder Taxbird auszugeben. Noch nicht implementiert.',
   'In Lx-Office 2.4.0 the administrator has to enter a list of units in the administrative section.' => 'In Lx-Office 2.4.0 muss der Administrator in den Systemeinstellungen eine Liste von verwendbaren Einheiten angeben.',
   'In-line'                     => 'im Text',
   'Include Exchangerate Difference' => 'Wechselkursunterschied einbeziehen',
   'Invno.'                      => 'Rg. Nr.',
   'Invnumber'                   => 'Rechnungsnummer',
   'Invoice'                     => 'Rechnung',
+  'Invoice (one letter abbreviation)' => 'R',
   'Invoice Date'                => 'Rechnungsdatum',
   'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
   'Invoice Duedate'             => 'Fälligkeitsdatum',
   'Invoice deleted!'            => 'Rechnung gelöscht!',
   'Invoices'                    => 'Rechnungen',
   'Is this a summary account to record' => 'Buchungskonto in',
-  'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)' => 'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)',
   'It is possible to do this automatically for some Buchungsgruppen, but not for all.' => 'Es ist möglich, dies für einige, aber nicht für alle Buchungsgruppen automatisch zu erledigen.',
   'It is possible to do this automatically for some units, but for others the user has to chose the new unit.' => 'Das ist für einige Einheiten automatisch möglich, aber bei anderen muss der Benutzer die neue Einheit auswählen.',
   'Item deleted!'               => 'Artikel gelöscht!',
   'July'                        => 'Juli',
   'Jun'                         => 'Jun',
   'June'                        => 'Juni',
-  'KNE Export erfolgreich!'     => 'KNE-Export erfolgreich!',
+  'KNE-Export erfolgreich!'     => 'KNE-Export erfolgreich!',
   'KNr. beim Kunden'            => 'KNr. beim Kunden',
-  'Kein Firmenname hinterlegt!' => 'Kein Firmenname hinterlegt!',
-  'Keine Firmenadresse hinterlegt!' => 'Keine Firmenadresse hinterlegt!',
-  'Kontakt'                     => 'Kontakt',
   'Konten'                      => 'Konten',
-  'Konto: '                     => 'Konto: ',
-  'Kontonummer'                 => 'Kontonummer',
   'Kontonummernerweiterung (KNE)' => 'Kontonummernerweiterung (KNE)',
   'Korrektur'                   => 'Korrektur',
-  'Kreditinstitut'              => 'Kreditinstitut',
   'Kundennummer'                => 'Kundennummer',
   'L'                           => 'L',
-  'LaTeX Templates'             => 'LaTeX-Vorlagen',
   'Language'                    => 'Sprache',
   'Language Values'             => 'Sprachübersetzungen',
   'Language deleted!'           => 'Sprache gelöscht!',
   'List Pricegroups'            => 'Preisgruppen anzeigen',
   'List Printer'                => 'Drucker anzeigen',
   'List Transactions'           => 'Buchungsliste',
+  'Local Tax Office Preferences' => 'Angaben zum Finanzamt',
   'Lock System'                 => 'System sperren',
   'Lockfile created!'           => 'System gesperrt!',
   'Lockfile removed!'           => 'System entsperrt!',
   'Login Name'                  => 'Benutzername',
   'Login name missing!'         => 'Loginname fehlt.',
   'Logout'                      => 'Abmeldung',
+  'Long Dates'                  => 'Lange Monatsnamen',
   'Long Description'            => 'Langtext',
   'Lx-Office 2.4.0 introduces two new concepts: tax zones and Buchungsgruppen.' => 'Lx-Office 2.4.0 führt zwei neue Konzepte ein: Steuerzonen und Buchungsgruppen.',
   'Lx-Office is about to update the database <b><TMPL_VAR dbname ESCAPE=HTML></b>. You should create a backup of the database before proceeding because the backup might not be reversible.' => 'Lx-Office wird gleich die Datenbank <b><TMPL_VAR dbname ESCAPE=HTML></b> aktualisieren. Sie sollten eine Sicherungskopie der Datenbank erstellen, bevor Sie fortfahren, da die Aktualisierung unter Umständen nicht umkehrbar ist.',
   'Method'                      => 'Verfahren',
   'Microfiche'                  => 'Mikrofilm',
   'Minimum Amount'              => 'Mindestbetrag',
+  'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
+  'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
   'Missing Method!'             => 'Fehlender Voranmeldungszeitraum',
   'Missing Preferences: Outputroutine disabled' => 'Die Ausgabefunktionen sind wegen unzureichender Voreinstellungen deaktiviert!',
   'Missing Tax Authoritys Preferences' => 'Fehlende Angaben zum Finanzamt!',
   'Model'                       => 'Modell',
   'Monat'                       => 'Monat',
   'Monthly'                     => 'monatlich',
+  'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Multibyte Encoding'          => 'Schriftsatz',
   'MwSt. inkl.'                 => 'MwSt. inkl.',
   'N/A'                         => 'N.Z.',
   'New unit'                    => 'Neue Einheit',
   'Next Dunning Level'          => 'Nächste Mahnstufe',
   'No'                          => 'Nein',
+  'No Company Address given'    => 'Keine Firmenadresse hinterlegt!',
+  'No Company Name given'       => 'Kein Firmenname hinterlegt!',
   'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
   'No Database Drivers available!' => 'Kein Datenbanktreiber verfügbar!',
   'No Dataset selected!'        => 'Keine Datenbank ausgewählt!',
   'Number'                      => 'Nummer',
   'Number Format'               => 'Zahlenformat',
   'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'Number of copies'            => 'Anzahl Kopien',
   'O'                           => 'O',
-  'OBE Export erfolgreich!'     => 'OBE-Export erfolgreich!',
+  'OBE-Export erfolgreich!'     => 'OBE-Export erfolgreich!',
   'Obsolete'                    => 'Ungültig',
   'Oct'                         => 'Okt',
   'October'                     => 'Oktober',
+  'Old (on the side)'           => 'Alt (seitlich)',
   'On Hand'                     => 'Auf Lager',
   'On Order'                    => 'Ist bestellt',
   'Open'                        => 'Offen',
   'OpenDocument/OASIS'          => 'OpenDocument/OASIS',
+  'Openings'                    => 'Öffnungszeiten',
   'Oracle Database Administration' => 'Oracle Datenbankadministration',
   'Order'                       => 'Auftrag',
   'Order Date'                  => 'Auftragsdatum',
   'Out of balance transaction!' => 'Buchung ist nicht ausgeglichen!',
   'Out of balance!'             => 'Summen stimmen nicht berein!',
   'Output Number Format'        => 'Zahlenformat (Ausgabe)',
+  'Outputformat'                => 'Ausgabeformat',
   'Own Product'                 => 'eigenes Produkt',
   'PDF'                         => 'PDF',
   'PDF (OpenDocument/OASIS)'    => 'PDF (OpenDocument/OASIS)',
-  'PLZ, Ort'                    => 'PLZ, Ort',
   'Packing List'                => 'Lieferschein',
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Please select a customer from the list below.' => 'Bitte einen Endkunden aus der Liste auswählen',
   'Please select a vendor from the list below.' => 'Bitte einen Händler aus der Liste auswählen',
   'Please select the chart of accounts this installation is using from the list below.' => 'Bitte wählen Sie den Kontenrahmen aus, der bei dieser Installation verwendet wird.',
+  'Plural'                      => 'Plural',
   'Port'                        => 'Port',
   'Port missing!'               => 'Portangabe fehlt!',
   'Post'                        => 'Buchen',
   'Pricegroups'                 => 'Preisgruppen',
   'Print'                       => 'Drucken',
   'Print and Post'              => 'Drucken und Buchen',
+  'Print options'               => 'Druckoptionen',
   'Printed'                     => 'gedruckt.',
   'Printer'                     => 'Drucker',
   'Printer Command'             => 'Druckbefehl',
   'Shopartikel'                 => 'Shopartikel',
   'Short'                       => 'kurz',
   'Show'                        => 'Zeigen',
+  'Show by default'             => 'Standardmäßig anzeigen',
+  'Show details'                => 'Details anzeigen',
   'Show old dunnings'           => 'Alte Mahnungen anzeigen',
   'Signature'                   => 'Unterschrift',
   'Skonto'                      => 'Skonto',
   'Step 2 of 3: Services'       => 'Schritt 2 von 3: Dienstleistungen',
   'Step 3 of 3: Assemblies'     => 'Schritt 3 von 3: Erzeugnisse',
   'Step 3 of 3: Default units'  => 'Schritt 3 von 3: Standardeinheiten',
-  'Steuerberater/-in'           => 'Steuerberater/-in',
-  'Steuernummer'                => 'Steuernummer',
-  'Steuernummer: '              => 'Steuernummer: ',
   'Steuersatz'                  => 'Steuersatz',
   'Stock'                       => 'einlagern',
   'Stock Assembly'              => 'Erzeugnis einlagern',
   'Storno'                      => 'Storno',
+  'Storno (one letter abbreviation)' => 'S',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
-  'Straße'                      => 'Straße',
   'Street'                      => 'Straße',
   'Stylesheet'                  => 'Stilvorlage',
   'Subject'                     => 'Betreff',
   'TOP100'                      => 'Top 100',
   'Tax'                         => 'Steuer',
   'Tax Accounts'                => 'Steuerkonto',
+  'Tax Consultant'              => 'Steuerberater/-in',
   'Tax Included'                => 'Steuer im Preis inbegriffen',
   'Tax Number'                  => 'Steuernummer',
   'Tax Number / SSN'            => 'Steuernummer',
+  'Tax Office'                  => 'Finanzamt',
+  'Tax Office Preferences'      => 'Finanzamt - Einstellungen',
+  'Tax Period'                  => 'Voranmeldungszeitraum',
   'Tax collected'               => 'vereinnahmte Steuer',
+  'Tax number'                  => 'Steuernummer',
   'Tax paid'                    => 'Vorsteuer',
   'Taxable'                     => 'Steuerpflichtig',
+  'Taxation'                    => 'Versteuerungs Verfahren',
   'Taxkey'                      => 'Steuerschlüssel',
-  'Tel. : '                     => 'Tel. : ',
-  'Tel.: '                      => 'Tel.: ',
-  'Telefon'                     => 'Telefon',
+  'Tel'                         => 'Tel',
+  'Telephone'                   => 'Telefon',
   'Template'                    => 'Druckvorlage',
   'Template Code'               => 'Vorlagenkürzel',
   'Template Code missing!'      => 'Vorlagenkürzel fehlt!',
   'Template saved!'             => 'Schablone gespeichert!',
   'Templates'                   => 'Vorlagen',
   'Terms missing in row '       => '+Tage fehlen in Zeile ',
-  'Terms: Net'                  => 'Zahlungsziel',
+  'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.',
   'The base unit does not exist or it is about to be deleted in row %d.' => 'Die Basiseinheit in Zeile %d existiert nicht oder soll gelöscht werden.',
   'The base unit does not exist.' => 'Die Basiseinheit existiert nicht.',
   'The base unit relations must not contain loops (e.g. by saying that unit A\'s base unit is B, B\'s base unit is C and C\'s base unit is A) in row %d.' => 'Die Beziehungen der Einheiten dürfen keine Schleifen beinhalten (z.B. wenn gesagt wird, dass Einheit As Basiseinheit B, Bs Basiseinheit C und Cs Basiseinheit A ist) in Zeile %d.',
   'This upgrade script tries to map all existing units in the database to the newly created units.' => 'Dieses Update-Script versucht, alle bestehenden Einheiten automatisch in die neuen Einheiten umzuwandeln.',
   'Title'                       => 'Titel',
   'To'                          => 'An',
+  'To (time)'                   => 'Bis',
   'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Um einer Gruppe einen neuen Benutzer hinzuzufügen, ändern und speichern Sie am einfachsten einen bestehen den Zugriffsnamen. Unter dem neuen Namen wird dann ein Benutzer mit denselben Einstellungen angelegt.',
+  'Top (CSS)'                   => 'Oben (mit CSS)',
+  'Top (Javascript)'            => 'Oben (mit Javascript)',
   'Top 100'                     => 'Top 100',
   'Top 100 hinzufuegen'         => 'Top 100 hinzufügen',
   'Top Level'                   => 'Hauptartikelbezeichnung',
   'Transfer Inventory'          => 'Ware umlagern',
   'Transfer to'                 => 'umlagern nach',
   'Trial Balance'               => 'Saldenbilanz',
+  'Type'                        => 'Typ',
   'Type of Business'            => 'Kundentyp',
   'USTVA-Hint: Method'          => 'Wenn Sie Ist-Versteuert sind, wählen Sie die Einnahmen-/Überschuß-Rechnung aus. Sind Sie Soll-Versteuert und bilanzverpflichtet, dann wählen Sie Bilanz aus.',
   'USTVA-Hint: Tax Authoritys'  => 'Bitte das Bundesland UND die Stadt bzw. den Einzugsbereich Ihres zuständigen Finanzamts auswählen.',
   'USt-IdNr.'                   => 'USt-IdNr.',
   'UStVA'                       => 'UStVA',
-  'UStVA 2004'                  => 'UStVA 2004',
-  'UStVA 2005'                  => 'UStVA 2005',
-  'UStVA 2006'                  => 'UStVA 2006',
-  'UStVA als PDF-Dokument'      => 'UStVa als PDF-Dokument',
+  'UStVA (PDF-Dokument)'        => 'UStVa als PDF-Dokument',
   'UStVA-Nr. 35'                => 'Kz. 35',
   'UStVA-Nr. 36'                => 'Kz. 36',
   'UStVA-Nr. 39'                => 'Kz. 37',
   'Unit'                        => 'Einheit',
   'Unit of measure'             => 'Maßeinheit',
   'Units'                       => 'Einheiten',
+  'Unknown dependency \'%s\'.'  => 'Unbekannte Abhängigkeit \'%s\'.',
   'Unlock System'               => 'System entsperren',
   'Until'                       => 'Bis',
   'Update'                      => 'Erneuern',
   'Update complete'             => 'Update beendet.',
   'Update prices'               => 'Preise aktualisieren',
   'Updated'                     => 'Erneuert am',
+  'Use As Template'             => 'Als Vorlage verwenden',
   'Use Templates'               => 'benutze Vorlagen',
   'User'                        => 'Benutzer',
+  'User Config'                 => 'Benutzereinstellungen',
   'User deleted!'               => 'Benutzer gelöscht!',
   'User saved!'                 => 'Benutzer gespeichert!',
   'Username'                    => 'Benutzername',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'Vendor saved!'               => 'Lieferant gespeichert!',
   'Vendors'                     => 'Lieferanten',
-  'Verfahren'                   => 'Verfahren',
-  'Verrechnung des Erstattungsbetrages erwünscht (Zeile 71)' => 'Verrechnung des Erstattungsbetrages erwünscht (Zeile 71)',
   'Verrechnungseinheit'         => 'Verrechnungseinheit',
   'Version'                     => 'Version',
   'View License'                => 'Lizenz ansehen',
   'Von Konto: '                 => 'von Konto: ',
-  'Voranmeldezeitraum'          => 'Voranmeldezeitraum',
-  'Voranmeldungszeitraum'       => 'Voranmeldungszeitraum',
-  'Vorschau'                    => 'Vorschau',
   'WEBDAV-Zugriff'              => 'WEBDAV-Zugriff',
   'Warehouse'                   => 'Lager',
   'Warehouse deleted!'          => 'Das Lager wurde gelöscht.',
   'Warehouses'                  => 'Lager',
   'Warnings during template upgrade' => 'Warnungen bei Aktualisierung der Dokumentenvorlagen',
   'Weight'                      => 'Gewicht',
-  'Weight Unit'                 => 'Gewichtseinheit',
   'What type of item is this?'  => 'Was ist dieser Artikel?',
+  'With Extension Of Time'      => 'mit Dauerfristverlängerung',
   'Workflow purchase_order'     => 'Workflow Lieferantenauftrag',
   'Workflow request_quotation'  => 'Workflow Preisanfrage',
   'Workflow sales_order'        => 'Workflow Auftrag',
   'Year'                        => 'Jahr',
   'Year End'                    => 'Jahresende',
   'Yearly'                      => 'jährlich',
+  'Yearly taxreport not yet implemented' => 'Jährlicher Steuerreport für dieses Ausgabeformat noch nicht implementiert',
   'Yes'                         => 'Ja',
   'You are logged out!'         => 'Auf Wiedersehen!',
   'You can also create new units now.' => 'Sie können jetzt auch neue Einheiten anlegen.',
   'You have to create new Buchungsgruppen for all the combinations of inventory, income and expense accounts that have been used already.' => 'Sie müssen neue Buchungsgruppen für alle Kombinationen aus Inventar-, Erlös- und Aufwandskonto, die bereits benutzt wurden.',
   'You must enter a host and port for local and remote connections!' => '"Rechner" und "Port" müssen für lokale und externe Verbindungen eingetragen werden!',
   'Zeitraum'                    => 'Zeitraum',
+  'Zip, City'                   => 'PLZ, Ort',
   'Zipcode'                     => 'PLZ',
   'accrual'                     => 'Bilanzierung (Soll-Versteuerung)',
   'as at'                       => 'zum Stand',
   'config'                      => 'Konfiguration',
   'continue'                    => 'weiter',
   'customernumber not unique!'  => 'Die Kundennummer ist schon vergeben',
-  'days'                        => 'Tage',
   'debug'                       => 'Debug',
   'deliverydate'                => 'Lieferdatum',
   'dimension units'             => 'Maßeinheiten',
   'month'                       => 'monatliche Abgabe',
   'none (pricegroup)'           => 'keine',
   'number'                      => 'Nummer',
+  'plural first char'           => 'P',
   'posted!'                     => 'gebucht',
   'prices updated!'             => ' Preise aktualisiert!',
   'quarter'                     => 'vierteljährliche (quartalsweise) Abgabe',
   'sent'                        => 'gesendet',
   'sent to printer'             => 'an Drucker geschickt',
   'service units'               => 'Dienstleistungseinheiten',
+  'singular first char'         => 'S',
   'soldtotal'                   => 'Verkaufte Anzahl',
   'successfully created!'       => 'wurde erfolgreich erstellt',
   'successfully deleted!'       => 'wurde erfolgreich gelöscht',
+  'to (date)'                   => 'bis',
+  'use program settings'        => 'benutze Programmeinstellungen',
   'ustva'                       => 'UStVA',
   'website'                     => 'Webseite',
   'winston_export'              => 'Winston-Export',
-  'Öffnungszeiten'              => 'Öffnungszeiten',
 };
 
 1;
 
   'Continue'                    => 'Weiter',
   'Copy to COA'                 => 'In Kontenplan kopieren',
   'Cost Center'                 => 'Kostenstelle',
+  'Costs'                       => 'Kosten',
   'Credit'                      => 'Haben',
   'Customer Number'             => 'Kundennummer',
   'Customernumberinit'          => 'Kundennummernkreis',
   'Dataset upgrade'             => 'Datenbankaktualisierung',
   'Date Format'                 => 'Datumsformat',
   'Debit'                       => 'Soll',
+  'Default template format'     => 'Standardvorlagenformat',
   'Delete'                      => 'Löschen',
   'Delete Account'              => 'Konto löschen',
   'Department deleted!'         => 'Abteilung gelöscht.',
   'Department saved!'           => 'Abteilung gespeichert.',
   'Departments'                 => 'Abteilungen',
+  'Dependency loop detected:'   => 'Schleife in den Abhängigkeiten entdeckt:',
   'Description'                 => 'Beschreibung',
   'Description missing!'        => 'Beschreibung fehlt.',
   'Discount'                    => 'Rabatt',
   'Erlöse EU m. UStId'          => 'Erlöse EU m. UStId',
   'Erlöse EU o. UStId'          => 'Erlöse EU o. UStId',
   'Erlöse Inland'               => 'Erlöse Inland',
+  'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
   'Expense'                     => 'Aufwandskonto',
   'Expense Account'             => 'Aufwandskonto',
   'Expense/Asset'               => 'Aufwand/Anlagen',
   'Folgekonto'                  => 'Folgekonto',
   'Foreign Exchange Gain'       => 'Wechselkurserträge',
   'Foreign Exchange Loss'       => 'Wechselkursaufwendungen',
+  'Form details (second row)'   => 'Formulardetails (zweite Positionszeile)',
   'GIFI'                        => 'GIFI',
   'GIFI deleted!'               => 'GIFI gelöscht!',
   'GIFI missing!'               => 'GIFI fehlt!',
   'GIFI saved!'                 => 'GIFI gespeichert!',
   'Gültig ab'                   => 'Gültig ab',
   'Heading'                     => 'Überschrift',
+  'Hide by default'             => 'Standardmäßig verstecken',
   'Include in drop-down menus'  => 'In Aufklappmenü aufnehmen',
   'Input Number Format'         => 'Zahlenformat (Eingabe)',
   'Inventory'                   => 'Inventar',
   'Lead'                        => 'Kundenquelle',
   'Liability'                   => 'Passiva/Mittelherkunft',
   'Link'                        => 'Verknüpfungen',
+  'Long Dates'                  => 'Lange Monatsnamen',
   'Long Description'            => 'Langtext',
+  'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
+  'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
+  'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
   'Netto Terms'                 => 'Zahlungsziel netto',
   'No'                          => 'Nein',
   'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'Number'                      => 'Nummer',
+  'Number Format'               => 'Zahlenformat',
+  'Number of copies'            => 'Anzahl Kopien',
+  'Old (on the side)'           => 'Alt (seitlich)',
+  'OpenDocument/OASIS'          => 'OpenDocument/OASIS',
   'Output Number Format'        => 'Zahlenformat (Ausgabe)',
+  'PDF'                         => 'PDF',
+  'PDF (OpenDocument/OASIS)'    => 'PDF (OpenDocument/OASIS)',
   'Part Number'                 => 'Artikelnummer',
   'Part description'            => 'Artikelbeschreibung',
   'Parts Inventory'             => 'Warenliste',
   'Payment terms deleted!'      => 'Zahlungskonditionen gelöscht!',
   'Phone'                       => 'Telefon',
   'Please enter values'         => 'Bitte Werte eingeben',
+  'Postscript'                  => 'Postscript',
   'Preferences saved!'          => 'Einstellungen gespeichert!',
+  'Print options'               => 'Druckoptionen',
   'Printer'                     => 'Drucker',
   'Printer Command'             => 'Druckbefehl',
   'Printer Command missing!'    => 'Druckbefehl fehlt',
   'Select an employee'          => 'Angestellten auswählen',
   'Service Items'               => 'Dienstleistungen',
   'Setup Menu'                  => 'Menüsetup',
+  'Show by default'             => 'Standardmäßig anzeigen',
   'Signature'                   => 'Unterschrift',
   'Skonto'                      => 'Skonto',
   'Skonto Terms'                => 'Zahlungsziel Skonto',
   'Template Code'               => 'Vorlagenkürzel',
   'Template Code missing!'      => 'Vorlagenkürzel fehlt!',
   'Template saved!'             => 'Schablone gespeichert!',
+  'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.',
   'The base unit does not exist or it is about to be deleted in row %d.' => 'Die Basiseinheit in Zeile %d existiert nicht oder soll gelöscht werden.',
   'The base unit does not exist.' => 'Die Basiseinheit existiert nicht.',
   'The base unit relations must not contain loops (e.g. by saying that unit A\'s base unit is B, B\'s base unit is C and C\'s base unit is A) in row %d.' => 'Die Beziehungen der Einheiten dürfen keine Schleifen beinhalten (z.B. wenn gesagt wird, dass Einheit As Basiseinheit B, Bs Basiseinheit C und Cs Basiseinheit A ist) in Zeile %d.',
   'The unit in row %d has been deleted in the meantime.' => 'Die Einheit in Zeile %d ist in der Zwischentzeit gelöscht worden.',
   'The unit in row %d has been used in the meantime and cannot be changed anymore.' => 'Die Einheit in Zeile %d wurde in der Zwischenzeit benutzt und kann nicht mehr geändert werden.',
   'The units have been saved.'  => 'Die Einheiten wurden gespeichert.',
+  'Top (CSS)'                   => 'Oben (mit CSS)',
+  'Top (Javascript)'            => 'Oben (mit Javascript)',
   'Transaction reversal enforced for all dates' => 'Fehleintragungen müssen für jeden Zeitraum mit einer Kontraeintragung ausgebessert werden',
   'Transaction reversal enforced up to' => 'Fehleintragungen können bis zu dem angegebenen Zeitraum nur mit einer Kontraeintragung ausgebessert werden!',
   'Type of Business'            => 'Kundentyp',
   'UStVA-Nr. 98'                => 'Kz. 98',
   'Umsatzsteuervoranmeldung'    => 'Umsatzsteuervoranmeldung',
   'Unit'                        => 'Einheit',
+  'Unknown dependency \'%s\'.'  => 'Unbekannte Abhängigkeit \'%s\'.',
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Warehouse deleted!'          => 'Das Lager wurde gelöscht.',
   'Warehouse saved!'            => 'Das Lager wurde gespeichert.',
   'Warehouses'                  => 'Lager',
-  'Weight Unit'                 => 'Gewichtseinheit',
   'Year End'                    => 'Jahresende',
   'Yes'                         => 'Ja',
   'dimension units'             => 'Maßeinheiten',
   'lead deleted!'               => 'Kundenquelle gelöscht',
   'lead saved!'                 => 'Kundenquelle geichert',
   'service units'               => 'Dienstleistungseinheiten',
+  'use program settings'        => 'benutze Programmeinstellungen',
 };
 
 $self->{subs} = {
   'edit_warehouse'              => 'edit_warehouse',
   'employee_selection_internal' => 'employee_selection_internal',
   'form_footer'                 => 'form_footer',
+  'format_dates'                => 'format_dates',
   'gifi_footer'                 => 'gifi_footer',
   'gifi_header'                 => 'gifi_header',
   'language_header'             => 'language_header',
   'payment_header'              => 'payment_header',
   'printer_header'              => 'printer_header',
   'project_selection_internal'  => 'project_selection_internal',
+  'reformat_numbers'            => 'reformat_numbers',
   'restore_form'                => 'restore_form',
   'save'                        => 'save',
   'save_account'                => 'save_account',
   'select_part'                 => 'select_part',
   'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
+  'set_unit_languages'          => 'set_unit_languages',
   'sic_header'                  => 'sic_header',
   'vendor_selection'            => 'vendor_selection',
   'warehouse_header'            => 'warehouse_header',
 
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Payments'                    => 'Zahlungsausgänge',
   'Post'                        => 'Buchen',
-  'Post as new'                 => 'Neu buchen',
   'Project'                     => 'Projekt',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Remaining'                   => 'Rest',
   'Transaction deleted!'        => 'Buchung gelöscht!',
   'Transaction posted!'         => 'Buchung verbucht!',
   'Update'                      => 'Erneuern',
+  'Use As Template'             => 'Als Vorlage verwenden',
   'Vendor'                      => 'Lieferant',
   'Vendor Invoice'              => 'Einkaufsrechnung',
   'Vendor missing!'             => 'Lieferant fehlt!',
   'select_name'                 => 'select_name',
   'select_project'              => 'select_project',
   'update'                      => 'update',
+  'use_as_template'             => 'use_as_template',
   'vendor_invoice'              => 'vendor_invoice',
   'yes'                         => 'yes',
   'kreditorenbuchung'           => 'ap_transaction',
   'löschen'                     => 'delete',
   'kreditorenbuchung_bearbeiten' => 'edit_accounts_payables_transaction',
   'buchen'                      => 'post',
-  'neu_buchen'                  => 'post_as_new',
   'erneuern'                    => 'update',
+  'als_vorlage_verwenden'       => 'use_as_template',
   'einkaufsrechnung'            => 'vendor_invoice',
   'ja'                          => 'yes',
 };
 
   'Confirm!'                    => 'Bestätigen Sie!',
   'Continue'                    => 'Weiter',
   'Credit Limit'                => 'Kreditlimit',
+  'Credit note (one letter abbreviation)' => 'G',
   'Currency'                    => 'Währung',
   'Customer'                    => 'Kunde',
   'Customer missing!'           => 'Kundenname fehlt!',
   'Include in Report'           => 'In Bericht aufnehmen',
   'Incoming Payments'           => 'Zahlungseingänge',
   'Invoice'                     => 'Rechnung',
+  'Invoice (one letter abbreviation)' => 'R',
   'Invoice Date'                => 'Rechnungsdatum',
   'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
   'Invoice Number'              => 'Rechnungsnummer',
   'Paid'                        => 'bezahlt',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Post'                        => 'Buchen',
-  'Post as new'                 => 'Neu buchen',
   'Project'                     => 'Projekt',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Remaining'                   => 'Rest',
   'Ship via'                    => 'Transportmittel',
   'Shipping Point'              => 'Versandort',
   'Source'                      => 'Beleg',
+  'Storno (one letter abbreviation)' => 'S',
   'Subtotal'                    => 'Zwischensumme',
   'Tax'                         => 'Steuer',
   'Tax Included'                => 'Steuer im Preis inbegriffen',
   'Total'                       => 'Summe',
   'Transaction deleted!'        => 'Buchung gelöscht!',
   'Transaction posted!'         => 'Buchung verbucht!',
+  'Type'                        => 'Typ',
   'Update'                      => 'Erneuern',
+  'Use As Template'             => 'Als Vorlage verwenden',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'Yes'                         => 'Ja',
   'button'                      => '?',
   'select_name'                 => 'select_name',
   'select_project'              => 'select_project',
   'update'                      => 'update',
+  'use_as_template'             => 'use_as_template',
   'vendor_invoice'              => 'vendor_invoice',
   'yes'                         => 'yes',
   'debitorenbuchung'            => 'ar_transaction',
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
   'buchen'                      => 'post',
-  'neu_buchen'                  => 'post_as_new',
   'rechnung'                    => 'sales_invoice',
   'erneuern'                    => 'update',
+  'als_vorlage_verwenden'       => 'use_as_template',
   'ja'                          => 'yes',
 };
 
 
   'Discount'                    => 'Rabatt',
   'Due Date'                    => 'Fälligkeitsdatum',
   'E-mail'                      => 'eMail',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
   'Edit Credit Note'            => 'Gutschrift bearbeiten',
+  'Enter longdescription'       => 'Langtext eingeben',
   'Exch'                        => 'Wechselkurs.',
   'Exchangerate'                => 'Wechselkurs',
   'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
   'May '                        => 'Mai',
   'Memo'                        => 'Memo',
   'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'No.'                         => 'Position',
   'Notes'                       => 'Bemerkungen',
   'Nov'                         => 'Nov',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part'                        => 'Ware',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Terms'               => 'Zahlungskonditionen',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
   'Post'                        => 'Buchen',
   'Post as new'                 => 'Neu buchen',
   'Postscript'                  => 'Postscript',
   'Printer'                     => 'Drucker',
   'Proforma Invoice'            => 'Proformarechnung',
   'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project description'         => 'Projektbeschreibung',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Qty'                         => 'Menge',
   'Sales Order'                 => 'Kundenauftrag',
   'Salesperson'                 => 'Verkäufer',
   'Screen'                      => 'Bildschirm',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a part'               => 'Artikel auswählen',
+  'Select a project'            => 'Projekt auswählen',
+  'Select an employee'          => 'Angestellten auswählen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
   'Ship via'                    => 'Transportmittel',
   'Shipping Address'            => 'Lieferadresse',
   'Shipping Point'              => 'Versandort',
+  'Show details'                => 'Details anzeigen',
   'Source'                      => 'Beleg',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
   'Trade Discount'              => 'Rabatt',
   'Unit'                        => 'Einheit',
   'Update'                      => 'Erneuern',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'What type of item is this?'  => 'Was ist dieser Artikel?',
 };
 
 $self->{subs} = {
+  'H'                           => 'H',
   'acc_menu'                    => 'acc_menu',
   'add'                         => 'add',
   'add_transaction'             => 'add_transaction',
   'ap_transaction'              => 'ap_transaction',
   'ar_transaction'              => 'ar_transaction',
+  'calculate_qty'               => 'calculate_qty',
   'check_form'                  => 'check_form',
   'check_name'                  => 'check_name',
   'check_project'               => 'check_project',
   'credit_note_links'           => 'credit_note_links',
   'customer_details'            => 'customer_details',
   'delete'                      => 'delete',
+  'delivery_customer_selection' => 'delivery_customer_selection',
   'display'                     => 'display',
   'display_form'                => 'display_form',
   'display_row'                 => 'display_row',
   'e_mail'                      => 'e_mail',
   'edit'                        => 'edit',
+  'employee_selection_internal' => 'employee_selection_internal',
   'form_footer'                 => 'form_footer',
   'form_header'                 => 'form_header',
+  'format_dates'                => 'format_dates',
   'gl_transaction'              => 'gl_transaction',
   'invoicetotal'                => 'invoicetotal',
   'item_selected'               => 'item_selected',
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'prepare_credit_note'         => 'prepare_credit_note',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
   'project_selected'            => 'project_selected',
+  'project_selection_internal'  => 'project_selection_internal',
   'quotation'                   => 'quotation',
+  'reformat_numbers'            => 'reformat_numbers',
   'relink_accounts'             => 'relink_accounts',
   'request_for_quotation'       => 'request_for_quotation',
+  'restore_form'                => 'restore_form',
   'sales_invoice'               => 'sales_invoice',
+  'save_form'                   => 'save_form',
   'section_menu'                => 'section_menu',
+  'select_employee'             => 'select_employee',
+  'select_employee_internal'    => 'select_employee_internal',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
+  'set_duedate'                 => 'set_duedate',
+  'set_longdescription'         => 'set_longdescription',
   'set_pricegroup'              => 'set_pricegroup',
   'ship_to'                     => 'ship_to',
   'update'                      => 'update',
   'validate_items'              => 'validate_items',
   'vendor_details'              => 'vendor_details',
   'vendor_invoice'              => 'vendor_invoice',
+  'vendor_selection'            => 'vendor_selection',
   'yes'                         => 'yes',
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
 
   'calculate_qty'               => 'calculate_qty',
   'delivery_customer_selection' => 'delivery_customer_selection',
   'employee_selection_internal' => 'employee_selection_internal',
+  'format_dates'                => 'format_dates',
   'part_selection_internal'     => 'part_selection_internal',
   'project_selection_internal'  => 'project_selection_internal',
+  'reformat_numbers'            => 'reformat_numbers',
   'restore_form'                => 'restore_form',
   'save_form'                   => 'save_form',
   'select_employee'             => 'select_employee',
 
   'Bcc'                         => 'Bcc',
   'Billing Address'             => 'Rechnungsadresse',
   'Birthday'                    => 'Geburtstag',
-  'Bis'                         => 'bis',
   'Cannot delete customer!'     => 'Kunde kann nicht gelöscht werden!',
   'Cannot delete vendor!'       => 'Lieferant kann nicht gelöscht werden!',
   'Cc'                          => 'Cc',
   'Tax Number'                  => 'Steuernummer',
   'Tax Number / SSN'            => 'Steuernummer',
   'Taxable'                     => 'Steuerpflichtig',
-  'Terms: Net'                  => 'Zahlungsziel',
   'Title'                       => 'Titel',
+  'To (time)'                   => 'Bis',
   'Type of Business'            => 'Kundentyp',
   'USt-IdNr.'                   => 'USt-IdNr.',
   'Unit'                        => 'Einheit',
   'Vendors'                     => 'Lieferanten',
   'Zipcode'                     => 'PLZ',
   'customernumber not unique!'  => 'Die Kundennummer ist schon vergeben',
-  'days'                        => 'Tage',
   's'                           => 's',
 };
 
 
   'January'                     => 'Januar',
   'July'                        => 'Juli',
   'June'                        => 'Juni',
-  'KNE Export erfolgreich!'     => 'KNE-Export erfolgreich!',
+  'KNE-Export erfolgreich!'     => 'KNE-Export erfolgreich!',
   'Konten'                      => 'Konten',
   'Kontonummernerweiterung (KNE)' => 'Kontonummernerweiterung (KNE)',
   'Mandantennummer'             => 'Mandantennummer',
   'May'                         => 'Mai',
   'Monat'                       => 'Monat',
   'November'                    => 'November',
-  'OBE Export erfolgreich!'     => 'OBE-Export erfolgreich!',
+  'OBE-Export erfolgreich!'     => 'OBE-Export erfolgreich!',
   'October'                     => 'Oktober',
   'Password'                    => 'Passwort',
   'Quartal'                     => 'Quartal',
 
 $self->{subs} = {
   'continue'                    => 'continue',
+  'download'                    => 'download',
   'export'                      => 'export',
   'export2'                     => 'export2',
   'export3'                     => 'export3',
 
 gestartet',
   'Dunning overview'            => 'Mahnungsübersicht',
   'E-mail'                      => 'eMail',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
   'Edit Dunning Process Config' => 'Mahnwesenkonfiguration bearbeiten',
+  'Enter longdescription'       => 'Langtext eingeben',
   'Extended'                    => 'Gesamt',
   'Fax'                         => 'Fax',
   'Feb'                         => 'Feb',
   'May '                        => 'Mai',
   'Message'                     => 'Nachricht',
   'Minimum Amount'              => 'Mindestbetrag',
+  'Name'                        => 'Name',
   'Next Dunning Level'          => 'Nächste Mahnstufe',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'No.'                         => 'Position',
   'Notes'                       => 'Bemerkungen',
   'Nov'                         => 'Nov',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part'                        => 'Ware',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Terms missing in row ' => 'Zahlungsfrist fehlt in Zeile ',
   'Payment until'               => 'Zahlungseingänge bis',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
   'Postscript'                  => 'Postscript',
   'Price'                       => 'Preis',
   'Pricegroup'                  => 'Preisgruppe',
   'Printer'                     => 'Drucker',
   'Proforma Invoice'            => 'Proformarechnung',
   'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project description'         => 'Projektbeschreibung',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Qty'                         => 'Menge',
   'Save'                        => 'Speichern',
   'Screen'                      => 'Bildschirm',
   'Search Dunning'              => 'Mahnung suchen',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a part'               => 'Artikel auswählen',
+  'Select a project'            => 'Projekt auswählen',
+  'Select an employee'          => 'Angestellten auswählen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
   'Ship'                        => 'Lagerausgang',
   'Ship to'                     => 'Lieferadresse',
   'Shipping Address'            => 'Lieferadresse',
+  'Show details'                => 'Details anzeigen',
   'Show old dunnings'           => 'Alte Mahnungen anzeigen',
   'Start Dunning Process'       => 'Mahnprozess starten',
   'Storno Invoice'              => 'Stornorechnung',
   'Total Fees'                  => 'Kumulierte Gebühren',
   'Total Interest'              => 'Kumulierte Zinsen',
   'Unit'                        => 'Einheit',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'What type of item is this?'  => 'Was ist dieser Artikel?',
 };
 
 $self->{subs} = {
+  'H'                           => 'H',
   'acc_menu'                    => 'acc_menu',
   'add'                         => 'add',
   'add_transaction'             => 'add_transaction',
   'ap_transaction'              => 'ap_transaction',
   'ar_transaction'              => 'ar_transaction',
+  'calculate_qty'               => 'calculate_qty',
   'check_form'                  => 'check_form',
   'check_name'                  => 'check_name',
   'check_project'               => 'check_project',
   'continue'                    => 'continue',
   'customer_details'            => 'customer_details',
+  'delivery_customer_selection' => 'delivery_customer_selection',
   'display'                     => 'display',
   'display_form'                => 'display_form',
   'display_row'                 => 'display_row',
   'e_mail'                      => 'e_mail',
   'edit_config'                 => 'edit_config',
+  'employee_selection_internal' => 'employee_selection_internal',
+  'format_dates'                => 'format_dates',
   'gl_transaction'              => 'gl_transaction',
   'invoicetotal'                => 'invoicetotal',
   'item_selected'               => 'item_selected',
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post_as_new'                 => 'post_as_new',
   'print'                       => 'print',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
   'project_selected'            => 'project_selected',
+  'project_selection_internal'  => 'project_selection_internal',
   'quotation'                   => 'quotation',
+  'reformat_numbers'            => 'reformat_numbers',
   'relink_accounts'             => 'relink_accounts',
   'request_for_quotation'       => 'request_for_quotation',
+  'restore_form'                => 'restore_form',
   'sales_invoice'               => 'sales_invoice',
   'save'                        => 'save',
   'save_dunning'                => 'save_dunning',
+  'save_form'                   => 'save_form',
   'search'                      => 'search',
   'section_menu'                => 'section_menu',
+  'select_employee'             => 'select_employee',
+  'select_employee_internal'    => 'select_employee_internal',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
+  'set_duedate'                 => 'set_duedate',
   'set_email'                   => 'set_email',
+  'set_longdescription'         => 'set_longdescription',
   'set_pricegroup'              => 'set_pricegroup',
   'ship_to'                     => 'ship_to',
   'show_dunning'                => 'show_dunning',
   'validate_items'              => 'validate_items',
   'vendor_details'              => 'vendor_details',
   'vendor_invoice'              => 'vendor_invoice',
+  'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
   'speichern'                   => 'save',
 };
 
   'Subtotal'                    => 'Zwischensumme',
   'Tax'                         => 'Steuer',
   'Taxkey'                      => 'Steuerschlüssel',
+  'To (time)'                   => 'Bis',
   'Transaction Date missing!'   => 'Buchungsdatum fehlt!',
   'Transaction deleted!'        => 'Buchung gelöscht!',
   'Update'                      => 'Erneuern',
 
   'Add Request for Quotation'   => 'Anfrage erfassen',
   'Add Sales Order'             => 'Auftrag erfassen',
   'Add Service'                 => 'Dienstleistung erfassen',
+  'Address'                     => 'Adresse',
   'Apr'                         => 'Apr',
   'April'                       => 'April',
   'Are you sure you want to update the prices' => 'Sind Sie sicher, dass Sie die Preise 
   'Discount'                    => 'Rabatt',
   'Drawing'                     => 'Zeichnung',
   'E-mail'                      => 'eMail',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
   'Edit '                       => 'Bearbeiten',
   'Edit Assembly'               => 'Erzeugnis bearbeiten',
   'Edit Part'                   => 'Ware bearbeiten',
   'Edit Service'                => 'Dienstleistung bearbeiten',
+  'Enter longdescription'       => 'Langtext eingeben',
   'Expense'                     => 'Aufwandskonto',
   'Extended'                    => 'Gesamt',
   'Fax'                         => 'Fax',
   'Microfiche'                  => 'Mikrofilm',
   'Model'                       => 'Modell',
   'Name'                        => 'Name',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'No.'                         => 'Position',
   'Not Discountable'            => 'Nicht rabattierfähig',
   'Notes'                       => 'Bemerkungen',
   'Part Description missing!'   => 'Artikelbezeichnung fehlt!',
   'Part Number'                 => 'Artikelnummer',
   'Part Number missing!'        => 'Artikelnummer fehlt!',
+  'Part description'            => 'Artikelbeschreibung',
   'Partnumber must not be set to empty!' => 'Die Artikelnummer darf nicht auf leer geändert werden.',
   'Partnumber not unique!'      => 'Artikelnummer bereits vorhanden!',
   'Parts'                       => 'Waren',
   'Payment Terms'               => 'Zahlungskonditionen',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
   'Postscript'                  => 'Postscript',
   'Preis'                       => 'Preis',
   'Preisklasse'                 => 'Preisgruppe',
   'Printer'                     => 'Drucker',
   'Proforma Invoice'            => 'Proformarechnung',
   'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project description'         => 'Projektbeschreibung',
   'Prozentual/Absolut'          => 'Prozentual/Absolut',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Qty'                         => 'Menge',
   'Save'                        => 'Speichern',
   'Save as new'                 => 'als neu speichern',
   'Screen'                      => 'Bildschirm',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a part'               => 'Artikel auswählen',
+  'Select a project'            => 'Projekt auswählen',
+  'Select an employee'          => 'Angestellten auswählen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
   'Sell Price'                  => 'Verkaufspreis',
   'Shipping Address'            => 'Lieferadresse',
   'Shopartikel'                 => 'Shopartikel',
   'Short'                       => 'kurz',
+  'Show details'                => 'Details anzeigen',
   'Sold'                        => 'Verkauft',
   'Stock'                       => 'einlagern',
   'Stock Assembly'              => 'Erzeugnis einlagern',
   'TOP100'                      => 'Top 100',
   'The formula needs the following syntax:<br>For regular article:<br>Variablename= Variable Unit;<br>Variablename2= Variable2 Unit2;<br>...<br>###<br>Variable + ( Variable2 / Variable )<br><b>Please be beware of the spaces in the formula</b><br>' => 'Die Formeln müssen in der folgenden Syntax eingegeben werden:<br>Bei normalen Artikeln:<br>Variablenname= Variable Einheit;<br>Variablenname2= Variable2 Einheit2;<br>...<br>###<br>Variable + Variable2 * ( Variable - Variable2 )<br>Bitte achten Sie auf die Leerzeichen in der Formel<br>Es muss jeweils die Gesamte Zeile eingegeben werden',
   'To'                          => 'An',
+  'To (time)'                   => 'Bis',
   'Top 100'                     => 'Top 100',
   'Top 100 hinzufuegen'         => 'Top 100 hinzufügen',
   'Top Level'                   => 'Hauptartikelbezeichnung',
   'Update'                      => 'Erneuern',
   'Update prices'               => 'Preise aktualisieren',
   'Updated'                     => 'Erneuert am',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
   'Vendor Number'               => 'Lieferantennummer',
   'Verrechnungseinheit'         => 'Verrechnungseinheit',
   'Weight'                      => 'Gewicht',
 };
 
 $self->{subs} = {
+  'H'                           => 'H',
   'acc_menu'                    => 'acc_menu',
   'add'                         => 'add',
   'addtop100'                   => 'addtop100',
   'assembly_row'                => 'assembly_row',
+  'calculate_qty'               => 'calculate_qty',
   'check_form'                  => 'check_form',
   'choice'                      => 'choice',
   'confirm_price_update'        => 'confirm_price_update',
   'continue'                    => 'continue',
   'customer_details'            => 'customer_details',
   'delete'                      => 'delete',
+  'delivery_customer_selection' => 'delivery_customer_selection',
   'display'                     => 'display',
   'display_form'                => 'display_form',
   'display_row'                 => 'display_row',
   'e_mail'                      => 'e_mail',
   'edit'                        => 'edit',
+  'employee_selection_internal' => 'employee_selection_internal',
   'form_footer'                 => 'form_footer',
   'form_header'                 => 'form_header',
+  'format_dates'                => 'format_dates',
   'generate_report'             => 'generate_report',
   'invoicetotal'                => 'invoicetotal',
   'item_selected'               => 'item_selected',
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'parts_language_selection'    => 'parts_language_selection',
   'parts_subtotal'              => 'parts_subtotal',
   'post_as_new'                 => 'post_as_new',
   'print'                       => 'print',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
+  'project_selection_internal'  => 'project_selection_internal',
   'quotation'                   => 'quotation',
+  'reformat_numbers'            => 'reformat_numbers',
   'relink_accounts'             => 'relink_accounts',
   'request_for_quotation'       => 'request_for_quotation',
   'restock_assemblies'          => 'restock_assemblies',
+  'restore_form'                => 'restore_form',
   'save'                        => 'save',
   'save_as_new'                 => 'save_as_new',
+  'save_form'                   => 'save_form',
   'search'                      => 'search',
   'search_update_prices'        => 'search_update_prices',
   'section_menu'                => 'section_menu',
+  'select_employee'             => 'select_employee',
+  'select_employee_internal'    => 'select_employee_internal',
   'select_item'                 => 'select_item',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'send_email'                  => 'send_email',
+  'set_duedate'                 => 'set_duedate',
+  'set_longdescription'         => 'set_longdescription',
   'set_pricegroup'              => 'set_pricegroup',
   'ship_to'                     => 'ship_to',
   'stock_assembly'              => 'stock_assembly',
   'update_prices'               => 'update_prices',
   'validate_items'              => 'validate_items',
   'vendor_details'              => 'vendor_details',
+  'vendor_selection'            => 'vendor_selection',
   'erfassen'                    => 'add',
   'erzeugnis_erfassen'          => 'add_assembly',
   'ware_erfassen'               => 'add_part',
 
   'Add Quotation'               => 'Angebot erfassen',
   'Add Request for Quotation'   => 'Anfrage erfassen',
   'Add Sales Order'             => 'Auftrag erfassen',
+  'Address'                     => 'Adresse',
   'Apr'                         => 'Apr',
   'April'                       => 'April',
   'Attachment'                  => 'als Anhang',
   'Department'                  => 'Abteilung',
   'Discount'                    => 'Rabatt',
   'E-mail'                      => 'eMail',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
+  'Enter longdescription'       => 'Langtext eingeben',
   'Extended'                    => 'Gesamt',
   'Fax'                         => 'Fax',
   'Feb'                         => 'Feb',
   'May'                         => 'Mai',
   'May '                        => 'Mai',
   'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'No.'                         => 'Position',
   'Nov'                         => 'Nov',
   'November'                    => 'November',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part'                        => 'Ware',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
   'Postscript'                  => 'Postscript',
   'Price'                       => 'Preis',
   'Pricegroup'                  => 'Preisgruppe',
   'Printer'                     => 'Drucker',
   'Proforma Invoice'            => 'Proformarechnung',
   'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project description'         => 'Projektbeschreibung',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Qty'                         => 'Menge',
   'Queue'                       => 'Warteschlange',
   'Required by'                 => 'Lieferdatum',
   'Sales Order'                 => 'Kundenauftrag',
   'Screen'                      => 'Bildschirm',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a part'               => 'Artikel auswählen',
+  'Select a project'            => 'Projekt auswählen',
+  'Select an employee'          => 'Angestellten auswählen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
   'Sep'                         => 'Sep',
   'Ship'                        => 'Lagerausgang',
   'Ship to'                     => 'Lieferadresse',
   'Shipping Address'            => 'Lieferadresse',
+  'Show details'                => 'Details anzeigen',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
   'Street'                      => 'Straße',
   'Subtotal'                    => 'Zwischensumme',
   'To'                          => 'An',
   'Unit'                        => 'Einheit',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
   'Vendor Number'               => 'Lieferantennummer',
   'What type of item is this?'  => 'Was ist dieser Artikel?',
   'Zipcode'                     => 'PLZ',
 };
 
 $self->{subs} = {
+  'H'                           => 'H',
+  'calculate_qty'               => 'calculate_qty',
   'check_form'                  => 'check_form',
   'customer_details'            => 'customer_details',
+  'delivery_customer_selection' => 'delivery_customer_selection',
   'display_form'                => 'display_form',
   'display_row'                 => 'display_row',
   'e_mail'                      => 'e_mail',
+  'employee_selection_internal' => 'employee_selection_internal',
+  'format_dates'                => 'format_dates',
   'invoicetotal'                => 'invoicetotal',
   'item_selected'               => 'item_selected',
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post_as_new'                 => 'post_as_new',
   'print'                       => 'print',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
+  'project_selection_internal'  => 'project_selection_internal',
   'quotation'                   => 'quotation',
+  'reformat_numbers'            => 'reformat_numbers',
   'relink_accounts'             => 'relink_accounts',
   'request_for_quotation'       => 'request_for_quotation',
+  'restore_form'                => 'restore_form',
+  'save_form'                   => 'save_form',
+  'select_employee'             => 'select_employee',
+  'select_employee_internal'    => 'select_employee_internal',
   'select_item'                 => 'select_item',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'send_email'                  => 'send_email',
+  'set_duedate'                 => 'set_duedate',
+  'set_longdescription'         => 'set_longdescription',
   'set_pricegroup'              => 'set_pricegroup',
   'ship_to'                     => 'ship_to',
   'validate_items'              => 'validate_items',
   'vendor_details'              => 'vendor_details',
+  'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
 };
 
 
   'Discount'                    => 'Rabatt',
   'Due Date'                    => 'Fälligkeitsdatum',
   'E-mail'                      => 'eMail',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
   'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
+  'Enter longdescription'       => 'Langtext eingeben',
   'Exch'                        => 'Wechselkurs.',
   'Exchangerate'                => 'Wechselkurs',
   'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
   'May '                        => 'Mai',
   'Memo'                        => 'Memo',
   'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'No.'                         => 'Position',
   'Notes'                       => 'Bemerkungen',
   'Nov'                         => 'Nov',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part'                        => 'Ware',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Payments'                    => 'Zahlungsausgänge',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
   'Post'                        => 'Buchen',
   'Post Payment'                => 'Zahlung buchen',
   'Postscript'                  => 'Postscript',
   'Printer'                     => 'Drucker',
   'Proforma Invoice'            => 'Proformarechnung',
   'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project description'         => 'Projektbeschreibung',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Qty'                         => 'Menge',
   'Required by'                 => 'Lieferdatum',
   'Sales Order'                 => 'Kundenauftrag',
   'Screen'                      => 'Bildschirm',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a part'               => 'Artikel auswählen',
+  'Select a project'            => 'Projekt auswählen',
+  'Select an employee'          => 'Angestellten auswählen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
   'Ship'                        => 'Lagerausgang',
   'Ship to'                     => 'Lieferadresse',
   'Shipping Address'            => 'Lieferadresse',
+  'Show details'                => 'Details anzeigen',
   'Source'                      => 'Beleg',
   'Steuersatz'                  => 'Steuersatz',
   'Storno'                      => 'Storno',
   'Total'                       => 'Summe',
   'Unit'                        => 'Einheit',
   'Update'                      => 'Erneuern',
+  'Use As Template'             => 'Als Vorlage verwenden',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
   'Vendor'                      => 'Lieferant',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor missing!'             => 'Lieferant fehlt!',
 };
 
 $self->{subs} = {
+  'H'                           => 'H',
   'acc_menu'                    => 'acc_menu',
   'add'                         => 'add',
   'add_transaction'             => 'add_transaction',
   'ap_transaction'              => 'ap_transaction',
   'ar_transaction'              => 'ar_transaction',
+  'calculate_qty'               => 'calculate_qty',
   'check_form'                  => 'check_form',
   'check_name'                  => 'check_name',
   'check_project'               => 'check_project',
   'continue'                    => 'continue',
   'customer_details'            => 'customer_details',
   'delete'                      => 'delete',
+  'delivery_customer_selection' => 'delivery_customer_selection',
   'display'                     => 'display',
   'display_form'                => 'display_form',
   'display_row'                 => 'display_row',
   'e_mail'                      => 'e_mail',
   'edit'                        => 'edit',
+  'employee_selection_internal' => 'employee_selection_internal',
   'form_footer'                 => 'form_footer',
   'form_header'                 => 'form_header',
+  'format_dates'                => 'format_dates',
   'gl_transaction'              => 'gl_transaction',
   'invoice_links'               => 'invoice_links',
   'invoicetotal'                => 'invoicetotal',
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'post_payment'                => 'post_payment',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
   'project_selected'            => 'project_selected',
+  'project_selection_internal'  => 'project_selection_internal',
   'quotation'                   => 'quotation',
+  'reformat_numbers'            => 'reformat_numbers',
   'relink_accounts'             => 'relink_accounts',
   'request_for_quotation'       => 'request_for_quotation',
+  'restore_form'                => 'restore_form',
   'sales_invoice'               => 'sales_invoice',
+  'save_form'                   => 'save_form',
   'section_menu'                => 'section_menu',
+  'select_employee'             => 'select_employee',
+  'select_employee_internal'    => 'select_employee_internal',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
+  'set_duedate'                 => 'set_duedate',
+  'set_longdescription'         => 'set_longdescription',
   'set_pricegroup'              => 'set_pricegroup',
   'ship_to'                     => 'ship_to',
   'storno'                      => 'storno',
   'update'                      => 'update',
+  'use_as_template'             => 'use_as_template',
   'validate_items'              => 'validate_items',
   'vendor_details'              => 'vendor_details',
   'vendor_invoice'              => 'vendor_invoice',
+  'vendor_selection'            => 'vendor_selection',
   'yes'                         => 'yes',
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
   'zahlung_buchen'              => 'post_payment',
   'storno'                      => 'storno',
   'erneuern'                    => 'update',
+  'als_vorlage_verwenden'       => 'use_as_template',
   'ja'                          => 'yes',
 };
 
 
   'Due Date'                    => 'Fälligkeitsdatum',
   'Dunning Amount'              => 'gemahnter Betrag',
   'E-mail'                      => 'eMail',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
   'Edit Credit Note'            => 'Gutschrift bearbeiten',
   'Edit Sales Invoice'          => 'Rechnung bearbeiten',
   'Edit Storno Credit Note'     => 'Storno Gutschrift bearbeiten',
   'Edit Storno Invoice'         => 'Stornorechnung bearbeiten',
+  'Enter longdescription'       => 'Langtext eingeben',
   'Exch'                        => 'Wechselkurs.',
   'Exchangerate'                => 'Wechselkurs',
   'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
   'May '                        => 'Mai',
   'Memo'                        => 'Memo',
   'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'No.'                         => 'Position',
   'Notes'                       => 'Bemerkungen',
   'Nov'                         => 'Nov',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part'                        => 'Ware',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Terms'               => 'Zahlungskonditionen',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Payments'                    => 'Zahlungsausgänge',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
   'Post'                        => 'Buchen',
   'Post Payment'                => 'Zahlung buchen',
   'Postscript'                  => 'Postscript',
   'Printer'                     => 'Drucker',
   'Proforma Invoice'            => 'Proformarechnung',
   'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project description'         => 'Projektbeschreibung',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Qty'                         => 'Menge',
   'Sales Order'                 => 'Kundenauftrag',
   'Salesperson'                 => 'Verkäufer',
   'Screen'                      => 'Bildschirm',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a part'               => 'Artikel auswählen',
+  'Select a project'            => 'Projekt auswählen',
+  'Select an employee'          => 'Angestellten auswählen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
   'Ship via'                    => 'Transportmittel',
   'Shipping Address'            => 'Lieferadresse',
   'Shipping Point'              => 'Versandort',
+  'Show details'                => 'Details anzeigen',
   'Source'                      => 'Beleg',
   'Steuersatz'                  => 'Steuersatz',
   'Storno'                      => 'Storno',
   'Trade Discount'              => 'Rabatt',
   'Unit'                        => 'Einheit',
   'Update'                      => 'Erneuern',
+  'Use As Template'             => 'Als Vorlage verwenden',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'What type of item is this?'  => 'Was ist dieser Artikel?',
 };
 
 $self->{subs} = {
+  'H'                           => 'H',
   'acc_menu'                    => 'acc_menu',
   'add'                         => 'add',
   'add_transaction'             => 'add_transaction',
   'ap_transaction'              => 'ap_transaction',
   'ar_transaction'              => 'ar_transaction',
+  'calculate_qty'               => 'calculate_qty',
   'check_form'                  => 'check_form',
   'check_name'                  => 'check_name',
   'check_project'               => 'check_project',
   'credit_note'                 => 'credit_note',
   'customer_details'            => 'customer_details',
   'delete'                      => 'delete',
+  'delivery_customer_selection' => 'delivery_customer_selection',
   'display'                     => 'display',
   'display_form'                => 'display_form',
   'display_row'                 => 'display_row',
   'e_mail'                      => 'e_mail',
   'edit'                        => 'edit',
+  'employee_selection_internal' => 'employee_selection_internal',
   'form_footer'                 => 'form_footer',
   'form_header'                 => 'form_header',
+  'format_dates'                => 'format_dates',
   'gl_transaction'              => 'gl_transaction',
   'invoice_links'               => 'invoice_links',
   'invoicetotal'                => 'invoicetotal',
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'post_payment'                => 'post_payment',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
   'project_selected'            => 'project_selected',
+  'project_selection_internal'  => 'project_selection_internal',
   'quotation'                   => 'quotation',
+  'reformat_numbers'            => 'reformat_numbers',
   'relink_accounts'             => 'relink_accounts',
   'request_for_quotation'       => 'request_for_quotation',
+  'restore_form'                => 'restore_form',
   'sales_invoice'               => 'sales_invoice',
+  'save_form'                   => 'save_form',
   'section_menu'                => 'section_menu',
+  'select_employee'             => 'select_employee',
+  'select_employee_internal'    => 'select_employee_internal',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
+  'set_duedate'                 => 'set_duedate',
+  'set_longdescription'         => 'set_longdescription',
   'set_pricegroup'              => 'set_pricegroup',
   'ship_to'                     => 'ship_to',
   'storno'                      => 'storno',
   'update'                      => 'update',
+  'use_as_template'             => 'use_as_template',
   'validate_items'              => 'validate_items',
   'vendor_details'              => 'vendor_details',
   'vendor_invoice'              => 'vendor_invoice',
+  'vendor_selection'            => 'vendor_selection',
   'yes'                         => 'yes',
   'weiter'                      => 'continue',
   'gutschrift'                  => 'credit_note',
   'lieferadresse'               => 'ship_to',
   'storno'                      => 'storno',
   'erneuern'                    => 'update',
+  'als_vorlage_verwenden'       => 'use_as_template',
   'ja'                          => 'yes',
 };
 
 
 $basedir  = "../..";
 $bindir   = "$basedir/bin/mozilla";
 $dbupdir  = "$basedir/sql/Pg-upgrade";
+$dbupdir2 = "$basedir/sql/Pg-upgrade2";
 $menufile = "menu.ini";
 $submitsearch = qr/type\s*=\s*[\"\']?submit/i;
 
 @dbplfiles = grep { /\.pl$/ } readdir DIR;
 closedir DIR;
 
+opendir DIR, $dbupdir2 or die "$!";
+@dbplfiles2 = grep { /\.pl$/ } readdir DIR;
+closedir DIR;
+
 # slurp the translations in
 if (-f 'all') {
   require "all";
 
 map({ handle_file($_, $bindir); } @progfiles);
 map({ handle_file($_, $dbupdir); } @dbplfiles);
+map({ handle_file($_, $dbupdir2); } @dbplfiles2);
 
 sub handle_file {
   my ($file, $dir) = @_;
 
   'Database Host'               => 'Datenbankcomputer',
   'Dataset'                     => 'Datenbank',
   'Dataset upgrade'             => 'Datenbankaktualisierung',
+  'Dependency loop detected:'   => 'Schleife in den Abhängigkeiten entdeckt:',
+  'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
   'Incorrect username or password!' => 'Ungültiger Benutzername oder falsches Passwort!',
   'Licensed to'                 => 'Lizensiert für',
   'Login'                       => 'Anmeldung',
   'Login Name'                  => 'Benutzername',
+  'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
+  'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
+  'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Password'                    => 'Passwort',
+  'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.',
+  'Unknown dependency \'%s\'.'  => 'Unbekannte Abhängigkeit \'%s\'.',
   'User'                        => 'Benutzer',
   'Version'                     => 'Version',
   'You are logged out!'         => 'Auf Wiedersehen!',
 
   'Buchungsgruppen'             => 'Buchungsgruppen',
   'Cash'                        => 'Zahlungsverkehr',
   'Chart of Accounts'           => 'Kontenübersicht',
-  'Check'                       => 'Scheck',
   'Checks'                      => 'Schecks',
   'Contacts'                    => 'Kontakte',
   'Customer'                    => 'Kunde',
   'Edit Dunning'                => 'Mahnungen konfigurieren',
   'General Ledger'              => 'Finanzbuchhaltung',
   'Groups'                      => 'Warengruppen',
-  'HTML Templates'              => 'HTML-Vorlagen',
   'Import CSV'                  => 'Import CSV',
   'Income Statement'            => 'GuV',
-  'Invoice'                     => 'Rechnung',
   'Invoices'                    => 'Rechnungen',
   'Journal'                     => 'Buchungsjournal',
-  'LaTeX Templates'             => 'LaTeX-Vorlagen',
   'Languages'                   => 'Sprachen',
   'Lead'                        => 'Kundenquelle',
   'Licenses'                    => 'Lizenzen',
   'List Printer'                => 'Drucker anzeigen',
   'Logout'                      => 'Abmeldung',
   'Master Data'                 => 'Stammdaten',
-  'Packing List'                => 'Lieferschein',
   'Packing Lists'               => 'Lieferschein',
   'Parts'                       => 'Waren',
   'Payment'                     => 'Zahlungsausgang',
   'Programm'                    => 'Programm',
   'Projects'                    => 'Projekte',
   'Projecttransactions'         => 'Projektbuchungen',
-  'Purchase Order'              => 'Lieferantenauftrag',
   'Purchase Orders'             => 'Lieferantenaufträge',
-  'Quotation'                   => 'Angebot',
   'Quotations'                  => 'Angebote',
-  'RFQ'                         => 'Anfrage',
   'RFQs'                        => 'Anfragen',
   'Receipt'                     => 'Zahlungseingang',
   'Receipts'                    => 'Zahlungseingänge',
   'Reconciliation'              => 'Kontenabgleich',
   'Reports'                     => 'Berichte',
   'Sales Invoices'              => 'Kundenrechnung',
-  'Sales Order'                 => 'Kundenauftrag',
   'Sales Orders'                => 'Aufträge',
   'Service units'               => 'Dienstleistungseinheiten',
   'Services'                    => 'Dienstleistungen',
   'Shipto'                      => 'Lieferanschriften',
-  'Statement'                   => 'Sammelrechnung',
   'Stylesheet'                  => 'Stilvorlage',
   'System'                      => 'System',
   'Trial Balance'               => 'Saldenbilanz',
   'Type of Business'            => 'Kundentyp',
-  'UStVA'                       => 'UStVA',
-  'UStVA 2004'                  => 'UStVA 2004',
-  'UStVA 2005'                  => 'UStVA 2005',
-  'UStVA 2006'                  => 'UStVA 2006',
   'UStVa'                       => 'UStVa',
   'UStVa Einstellungen'         => 'UStVa Einstellungen',
   'Units'                       => 'Einheiten',
 
   'Buchungsgruppen'             => 'Buchungsgruppen',
   'Cash'                        => 'Zahlungsverkehr',
   'Chart of Accounts'           => 'Kontenübersicht',
-  'Check'                       => 'Scheck',
   'Checks'                      => 'Schecks',
   'Contacts'                    => 'Kontakte',
   'Customer'                    => 'Kunde',
   'Edit Dunning'                => 'Mahnungen konfigurieren',
   'General Ledger'              => 'Finanzbuchhaltung',
   'Groups'                      => 'Warengruppen',
-  'HTML Templates'              => 'HTML-Vorlagen',
   'Import CSV'                  => 'Import CSV',
   'Income Statement'            => 'GuV',
-  'Invoice'                     => 'Rechnung',
   'Invoices'                    => 'Rechnungen',
   'Journal'                     => 'Buchungsjournal',
-  'LaTeX Templates'             => 'LaTeX-Vorlagen',
   'Languages'                   => 'Sprachen',
   'Lead'                        => 'Kundenquelle',
   'Licenses'                    => 'Lizenzen',
   'List Printer'                => 'Drucker anzeigen',
   'Logout'                      => 'Abmeldung',
   'Master Data'                 => 'Stammdaten',
-  'Packing List'                => 'Lieferschein',
   'Packing Lists'               => 'Lieferschein',
   'Parts'                       => 'Waren',
   'Payment'                     => 'Zahlungsausgang',
   'Programm'                    => 'Programm',
   'Projects'                    => 'Projekte',
   'Projecttransactions'         => 'Projektbuchungen',
-  'Purchase Order'              => 'Lieferantenauftrag',
   'Purchase Orders'             => 'Lieferantenaufträge',
-  'Quotation'                   => 'Angebot',
   'Quotations'                  => 'Angebote',
-  'RFQ'                         => 'Anfrage',
   'RFQs'                        => 'Anfragen',
   'Receipt'                     => 'Zahlungseingang',
   'Receipts'                    => 'Zahlungseingänge',
   'Reconciliation'              => 'Kontenabgleich',
   'Reports'                     => 'Berichte',
   'Sales Invoices'              => 'Kundenrechnung',
-  'Sales Order'                 => 'Kundenauftrag',
   'Sales Orders'                => 'Aufträge',
   'Service units'               => 'Dienstleistungseinheiten',
   'Services'                    => 'Dienstleistungen',
   'Shipto'                      => 'Lieferanschriften',
-  'Statement'                   => 'Sammelrechnung',
   'Stylesheet'                  => 'Stilvorlage',
   'System'                      => 'System',
   'Trial Balance'               => 'Saldenbilanz',
   'Type of Business'            => 'Kundentyp',
-  'UStVA'                       => 'UStVA',
-  'UStVA 2004'                  => 'UStVA 2004',
-  'UStVA 2005'                  => 'UStVA 2005',
-  'UStVA 2006'                  => 'UStVA 2006',
   'UStVa'                       => 'UStVa',
   'UStVa Einstellungen'         => 'UStVa Einstellungen',
   'Units'                       => 'Einheiten',
 
--- /dev/null
+$self->{texts} = {
+  'Logout'                      => 'Abmeldung',
+};
+
+$self->{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'clock_line'                  => 'clock_line',
+  'display'                     => 'display',
+  'my_length'                   => 'my_length',
+  'print_menu'                  => 'print_menu',
+};
+
+1;
 
   'Done'                        => 'Fertig',
   'Dunning Amount'              => 'gemahnter Betrag',
   'E-mail'                      => 'eMail',
-  'E-mail address missing!'     => 'eMailadresse fehlt!',
+  'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'E-mailed'                    => 'eMail gesendet.',
   'Edit Purchase Order'         => 'Lieferantenaufrag bearbeiten',
   'Edit Quotation'              => 'Angebot bearbeiten',
   'Edit the sales_order'        => 'Bearbeiten des Auftrags',
   'Edit the sales_quotation'    => 'Bearbeiten des Angebots',
   'Employee'                    => 'Bearbeiter',
+  'Enter longdescription'       => 'Langtext eingeben',
   'Exchangerate'                => 'Wechselkurs',
   'Exchangerate missing!'       => 'Es fehlt der Wechselkurs!',
   'Extended'                    => 'Gesamt',
   'May'                         => 'Mai',
   'May '                        => 'Mai',
   'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No project was found matching the search parameters.' => 'Es wurde kein Projekt gefunden, auf das die Suchparameter zutreffen.',
   'No.'                         => 'Position',
   'Notes'                       => 'Bemerkungen',
   'Nothing entered!'            => 'Es wurde nichts eingegeben.',
   'Part'                        => 'Ware',
   'Part Description'            => 'Artikelbeschreibung',
   'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Terms'               => 'Zahlungskonditionen',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
   'Postscript'                  => 'Postscript',
   'Price'                       => 'Preis',
   'Pricegroup'                  => 'Preisgruppe',
   'Printer'                     => 'Drucker',
   'Proforma Invoice'            => 'Proformarechnung',
   'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project description'         => 'Projektbeschreibung',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Purchase Orders'             => 'Lieferantenaufträge',
   'Quotation Number missing!'   => 'Angebotsnummer fehlt!',
   'Quotation deleted!'          => 'Angebot wurde gelöscht.',
   'Quotations'                  => 'Angebote',
+  'RFQ'                         => 'Anfrage',
   'RFQ Number'                  => 'Anfragenummer',
   'Recd'                        => 'erhalten',
   'Receive Merchandise'         => 'Waren einlagern',
   'Save and Close'              => 'Speichern und schließen',
   'Save as new'                 => 'als neu speichern',
   'Screen'                      => 'Bildschirm',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a part'               => 'Artikel auswählen',
+  'Select a project'            => 'Projekt auswählen',
+  'Select an employee'          => 'Angestellten auswählen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
   'Shipping Date'               => 'Lieferdatum',
   'Shipping Date missing!'      => 'Lieferdatum fehlt.',
   'Shipping Point'              => 'Versandort',
+  'Show details'                => 'Details anzeigen',
   'Steuersatz'                  => 'Steuersatz',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
   'Subtotal'                    => 'Zwischensumme',
   'Tax'                         => 'Steuer',
   'Tax Included'                => 'Steuer im Preis inbegriffen',
-  'Terms: Net'                  => 'Zahlungsziel',
   'To'                          => 'An',
   'Total'                       => 'Summe',
   'Trade Discount'              => 'Rabatt',
   'Unit'                        => 'Einheit',
   'Update'                      => 'Erneuern',
   'Valid until'                 => 'gültig bis',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
   'Vendor'                      => 'Lieferant',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor missing!'             => 'Lieferant fehlt!',
   'Yes'                         => 'Ja',
   'Zipcode'                     => 'PLZ',
   'button'                      => '?',
-  'days'                        => 'Tage',
   'ea'                          => 'St.',
   'emailed to'                  => 'gemailt an',
   'none (pricegroup)'           => 'keine',
 };
 
 $self->{subs} = {
+  'H'                           => 'H',
   'acc_menu'                    => 'acc_menu',
   'add'                         => 'add',
   'add_transaction'             => 'add_transaction',
   'ap_transaction'              => 'ap_transaction',
   'ar_transaction'              => 'ar_transaction',
   'backorder_exchangerate'      => 'backorder_exchangerate',
+  'calculate_qty'               => 'calculate_qty',
   'check_form'                  => 'check_form',
   'check_name'                  => 'check_name',
   'check_project'               => 'check_project',
   'create_backorder'            => 'create_backorder',
   'customer_details'            => 'customer_details',
   'delete'                      => 'delete',
+  'delivery_customer_selection' => 'delivery_customer_selection',
   'display'                     => 'display',
   'display_form'                => 'display_form',
   'display_row'                 => 'display_row',
   'done'                        => 'done',
   'e_mail'                      => 'e_mail',
   'edit'                        => 'edit',
+  'employee_selection_internal' => 'employee_selection_internal',
   'form_footer'                 => 'form_footer',
   'form_header'                 => 'form_header',
+  'format_dates'                => 'format_dates',
   'gl_transaction'              => 'gl_transaction',
   'invoice'                     => 'invoice',
   'invoicetotal'                => 'invoicetotal',
   'order'                       => 'order',
   'order_links'                 => 'order_links',
   'orders'                      => 'orders',
+  'part_selection_internal'     => 'part_selection_internal',
   'poso'                        => 'poso',
   'post_as_new'                 => 'post_as_new',
   'prepare_order'               => 'prepare_order',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
   'project_selected'            => 'project_selected',
+  'project_selection_internal'  => 'project_selection_internal',
   'purchase_order'              => 'purchase_order',
   'quotation'                   => 'quotation',
+  'reformat_numbers'            => 'reformat_numbers',
   'relink_accounts'             => 'relink_accounts',
   'request_for_quotation'       => 'request_for_quotation',
+  'restore_form'                => 'restore_form',
   'sales_invoice'               => 'sales_invoice',
   'sales_order'                 => 'sales_order',
   'save'                        => 'save',
   'save_and_close'              => 'save_and_close',
   'save_as_new'                 => 'save_as_new',
   'save_exchangerate'           => 'save_exchangerate',
+  'save_form'                   => 'save_form',
   'search'                      => 'search',
   'search_transfer'             => 'search_transfer',
   'section_menu'                => 'section_menu',
+  'select_employee'             => 'select_employee',
+  'select_employee_internal'    => 'select_employee_internal',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
+  'set_duedate'                 => 'set_duedate',
   'set_headings'                => 'set_headings',
+  'set_longdescription'         => 'set_longdescription',
   'set_pricegroup'              => 'set_pricegroup',
   'ship_receive'                => 'ship_receive',
   'ship_to'                     => 'ship_to',
   'validate_items'              => 'validate_items',
   'vendor_details'              => 'vendor_details',
   'vendor_invoice'              => 'vendor_invoice',
+  'vendor_selection'            => 'vendor_selection',
   'yes'                         => 'yes',
   'erfassen'                    => 'add',
   'weiter'                      => 'continue',
 
   '2. Quarter'                  => '2. Quartal',
   '3. Quarter'                  => '3. Quartal',
   '4. Quarter'                  => '4. Quartal',
+  'Account'                     => 'Konto',
+  'Account Nummer'              => 'Kontonummer',
   'Address'                     => 'Adresse',
-  'Angaben zum Finanzamt'       => 'Angaben zum Finanzamt',
-  'Application Error. No Format given!' => 'Fehler in der Anwendung. Das Format fehlt.',
-  'Application Error. Wrong Format: ' => 'Fehler in der Anwendung. Falsches Format: ',
+  'Amended Advance Turnover Tax Return' => 'Berichtigte Anmeldung',
+  'Amended Advance Turnover Tax Return (Nr. 10)' => 'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)',
+  'Application Error. No Format given' => 'Fehler in der Anwendung. Das Ausgabeformat fehlt.',
+  'Application Error. Wrong Format' => 'Fehler in der Anwendung. Falsches Format: ',
   'Apr'                         => 'Apr',
   'April'                       => 'April',
+  'Assume Tax Consultant Data in Tax Computation?' => 'Beraterdaten in UStVA übernehmen?',
   'Aug'                         => 'Aug',
   'August'                      => 'August',
-  'Ausgabeformat'               => 'Ausgabeformat',
-  'Ausgabeformat auswählen...'  => 'Ausgabeformat auswählen...',
-  'BLZ: '                       => 'BLZ: ',
-  'Back to user config...'      => 'Benutzereinstellungen',
-  'Bankleitzahl'                => 'Bankleitzahl',
-  'Bankleitzahl (BLZ)'          => 'Bankleitzahl (BLZ)',
-  'Bankverbindung'              => 'Bankverbindung',
-  'Bankverbindung des Finanzamts' => 'Bankverbindung des Finanzamts',
-  'Bankverbindungen'            => 'Bankverbindungen',
-  'Bankverbindungen des Finanzamts' => 'Bankverbindungen des Finanzamts',
-  'Beraterdaten in UStVA übernehmen?' => 'Beraterdaten in UStVA übernehmen?',
-  'Berichtigte Anmeldung'       => 'Berichtigte Anmeldung',
-  'Bitte Angaben überprüfen'    => 'Bitte Angaben überprüfen',
-  'Bitte alle Angaben überprüfen' => 'Bitte alle Angaben überprüfen',
-  'Bitte eine Steuernummer angeben' => 'Bitte eine Steuernummer angeben',
+  'Bank'                        => 'Bank',
+  'Bank Code'                   => 'BLZ: ',
+  'Bank Code (long)'            => 'Bankleitzahl (BLZ)',
+  'Bank Connection'             => 'Bankverbindung',
+  'Bank Connection Tax Office'  => 'Bankverbindung des Finanzamts',
+  'Check Details'               => 'Bitte Angaben überprüfen',
+  'Choose Outputformat'         => 'Ausgabeformat auswählen...',
+  'Choose a Tax Number'         => 'Bitte eine Steuernummer angeben',
+  'Clearing Tax Received (No 71)' => 'Verrechnung des Erstattungsbetrages erwünscht (Zeile 71)',
+  'Company'                     => 'Firma',
+  'Contact'                     => 'Kontakt',
   'Continue'                    => 'Weiter',
   'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
   'Dataset upgrade'             => 'Datenbankaktualisierung',
-  'Dauerfristverlängerung'      => 'Dauerfristverlängerung',
   'Dec'                         => 'Dez',
   'December'                    => 'Dezember',
+  'Dependency loop detected:'   => 'Schleife in den Abhängigkeiten entdeckt:',
   'Description'                 => 'Beschreibung',
-  'ELSTER Export nach Taxbird'  => 'ELSTER-Export nach Taxbird',
+  'ELSTER Export (Taxbird)'     => 'ELSTER-Export nach Taxbird',
+  'ELSTER Export (Winston)'     => 'ELSTER Export nach Winston',
   'ELSTER Export nach Winston'  => 'ELSTER Export nach Winston',
-  'ELSTER-Steuernummer: '       => 'ELSTER-Steuernummer: ',
+  'ELSTER Tax Number'           => 'ELSTER-Steuernummer: ',
+  'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
+  'Extension Of Time'           => 'Dauerfristverlängerung',
   'Fax'                         => 'Fax',
-  'Fax. : '                     => 'Fax. : ',
-  'Fax.: '                      => 'Fax.: ',
   'Feb'                         => 'Feb',
   'February'                    => 'Februar',
-  'Finanzamt'                   => 'Finanzamt',
-  'Finanzamt - Einstellungen'   => 'Finanzamt - Einstellungen',
-  'Firma'                       => 'Firma',
   'Help'                        => 'Hilfe',
-  'Help:'                       => 'Hilfe:',
   'Hint-Missing-Preferences'    => 'Bitte fehlende USTVA Einstellungen ergänzen (Menüpunkt: Programm)',
-  'Hinweise'                    => 'Hinweise',
-  'Impossible to create yearly Tax Report as PDF or Postscript<br \> Not yet implemented!' => 'Es ist noch nicht möglich, die Umsatzsteuervoranmeldung für das ganze Jahr als PDF oder Postscript auszugeben. Noch nicht implementiert.',
-  'Impossible to create yearly Tax Report via Winston or Taxbird.<br \> Not yet implemented!' => 'Es ist noch nicht möglich, die Umsatzsteuervoranmeldung für das ganze Jahr für Winston oder Taxbird auszugeben. Noch nicht implementiert.',
+  'Hints'                       => 'Hinweise',
   'Internet'                    => 'Internet',
-  'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)' => 'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)',
   'Jan'                         => 'Jan',
   'January'                     => 'Januar',
   'Jul'                         => 'Jul',
   'July'                        => 'Juli',
   'Jun'                         => 'Jun',
   'June'                        => 'Juni',
-  'Kein Firmenname hinterlegt!' => 'Kein Firmenname hinterlegt!',
-  'Keine Firmenadresse hinterlegt!' => 'Keine Firmenadresse hinterlegt!',
-  'Kontakt'                     => 'Kontakt',
-  'Konto: '                     => 'Konto: ',
-  'Kontonummer'                 => 'Kontonummer',
-  'Kreditinstitut'              => 'Kreditinstitut',
+  'Local Tax Office Preferences' => 'Angaben zum Finanzamt',
   'Mar'                         => 'März',
   'March'                       => 'März',
   'May'                         => 'Mai',
   'May '                        => 'Mai',
   'Method'                      => 'Verfahren',
+  'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
+  'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
   'Missing Method!'             => 'Fehlender Voranmeldungszeitraum',
   'Missing Preferences: Outputroutine disabled' => 'Die Ausgabefunktionen sind wegen unzureichender Voreinstellungen deaktiviert!',
   'Missing Tax Authoritys Preferences' => 'Fehlende Angaben zum Finanzamt!',
+  'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No Company Address given'    => 'Keine Firmenadresse hinterlegt!',
+  'No Company Name given'       => 'Kein Firmenname hinterlegt!',
   'Nov'                         => 'Nov',
   'November'                    => 'November',
   'Number'                      => 'Nummer',
   'Oct'                         => 'Okt',
   'October'                     => 'Oktober',
-  'PLZ, Ort'                    => 'PLZ, Ort',
+  'Openings'                    => 'Öffnungszeiten',
+  'Outputformat'                => 'Ausgabeformat',
+  'Preview'                     => 'Druckvorschau',
   'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
   'Select a period'             => 'Bitte Zeitraum auswählen',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Sep'                         => 'Sep',
   'September'                   => 'September',
   'Show'                        => 'Zeigen',
-  'Steuerberater/-in'           => 'Steuerberater/-in',
-  'Steuernummer'                => 'Steuernummer',
-  'Steuernummer: '              => 'Steuernummer: ',
-  'Straße'                      => 'Straße',
-  'Tel. : '                     => 'Tel. : ',
-  'Tel.: '                      => 'Tel.: ',
-  'Telefon'                     => 'Telefon',
+  'Street'                      => 'Straße',
+  'Tax Consultant'              => 'Steuerberater/-in',
+  'Tax Number'                  => 'Steuernummer',
+  'Tax Office'                  => 'Finanzamt',
+  'Tax Office Preferences'      => 'Finanzamt - Einstellungen',
+  'Tax Period'                  => 'Voranmeldungszeitraum',
+  'Taxation'                    => 'Versteuerungs Verfahren',
+  'Tel'                         => 'Tel',
+  'Telephone'                   => 'Telefon',
+  'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.',
   'USTVA-Hint: Method'          => 'Wenn Sie Ist-Versteuert sind, wählen Sie die Einnahmen-/Überschuß-Rechnung aus. Sind Sie Soll-Versteuert und bilanzverpflichtet, dann wählen Sie Bilanz aus.',
   'USTVA-Hint: Tax Authoritys'  => 'Bitte das Bundesland UND die Stadt bzw. den Einzugsbereich Ihres zuständigen Finanzamts auswählen.',
   'UStVA'                       => 'UStVA',
-  'UStVA als PDF-Dokument'      => 'UStVa als PDF-Dokument',
+  'UStVA (PDF-Dokument)'        => 'UStVa als PDF-Dokument',
+  'Unknown dependency \'%s\'.'  => 'Unbekannte Abhängigkeit \'%s\'.',
+  'User Config'                 => 'Benutzereinstellungen',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
-  'Verfahren'                   => 'Verfahren',
-  'Verrechnung des Erstattungsbetrages erwünscht (Zeile 71)' => 'Verrechnung des Erstattungsbetrages erwünscht (Zeile 71)',
-  'Voranmeldezeitraum'          => 'Voranmeldezeitraum',
-  'Voranmeldungszeitraum'       => 'Voranmeldungszeitraum',
-  'Vorschau'                    => 'Vorschau',
+  'With Extension Of Time'      => 'mit Dauerfristverlängerung',
   'Wrong Period'                => 'Falscher Zeitraum',
   'Year'                        => 'Jahr',
   'Yearly'                      => 'jährlich',
+  'Yearly taxreport not yet implemented' => 'Jährlicher Steuerreport für dieses Ausgabeformat noch nicht implementiert',
+  'Zip, City'                   => 'PLZ, Ort',
   'accrual'                     => 'Bilanzierung (Soll-Versteuerung)',
   'back'                        => 'zurück',
-  'bis'                         => 'bis',
   'cash'                        => 'E/Ü-Rechnung (Ist-Versteuerung)',
   'continue'                    => 'weiter',
   'debug'                       => 'Debug',
   'quarter'                     => 'vierteljährliche (quartalsweise) Abgabe',
   'save'                        => 'speichern',
   'saved'                       => 'gespeichert',
-  'Öffnungszeiten'              => 'Öffnungszeiten',
+  'to (date)'                   => 'bis',
 };
 
 $self->{subs} = {
 
 clearstatcache ();
 //print_r($_FILES);
 $test=$_POST["test"];
-if (!empty($_FILES["Datei"]["name"])) { 
+if (!empty($_FILES["Datei"]["name"])) {
        $file=$_POST["ziel"];
        if (!move_uploaded_file($_FILES["Datei"]["tmp_name"],$file.".csv")) {
                $file=false;
                echo "Upload von ".$_FILES["Datei"]["name"]." fehlerhaft. (".$_FILES["Datei"]["error"].")<br>";
-       } 
+       }
 } else if (is_file($_POST["ziel"].".csv")) {
        $file=$_POST["ziel"];
 } else {
        $file=false;
-} 
+}
 
 if (!$file) ende (2);
 
 $f=fopen("$file.csv","r");
 $zeile=fgets($f,1200);
 $infld=split($trenner,strtolower($zeile));
-//echo "$zeile<br>";
-//print_r($infld); echo "<br>";
 $first=true;
 $ok=true;
 foreach ($infld as $fld) {
                        continue;
                };
                $data=trim($data);
+               $data=mb_convert_encoding($data,"ISO-8859-15","auto");
                //$data=htmlentities($data);
                $data=addslashes($data);
-               if (trim($in_fld[$i])==$file."number") {  // customernumber || vendornumber
+               if ($in_fld[$i]==$file."number") {  // customernumber || vendornumber
                        if (empty($data) or !$data) {
-                               $data=getKdId(); 
+                               $data=getKdId();
                                $number=true;
                        } else {
                                $data=chkKdId($data);
                } else if ($in_fld[$i]=="taxincluded"){
                        $data=strtolower(substr($data,0,1));
                        if ($data!="f" && $data!="t") $data="f";
-               } else if ($in_fld[$i]=="language") {
-                       $data=strtolower(substr($data,0,2));
-                       if (!in_array($data,array("de","en","fr"))) $data=false;
-               }
-               if ($in_fld[$i]=="matchcode") {  
+               } else if ($in_fld[$i]=="ustid"){
+                       $data=strtr(" ","",$data);
+               } /*else if ($in_fld[$i]=="matchcode") {
                   $matchcode=$data;
                   $i++;
                   continue;
-                }
-
                 if ($data==false or empty($data) or !$data) {
                        if (in_array($in_fld[$i],array("name"))) {
                                $data=$matchcode;
-                       }                
+                       }
                }
+                }*/
+
                $keys.=$in_fld[$i].",";
                if ($data==false or empty($data) or !$data) {
-                       if (in_array($in_fld[$i],array("name"))) {
-                               $keys="(";
-                               break;
-                       }
                        $vals.="null,";
                } else {
                        if ($in_fld[$i]=="contact"){
                         //echo "Import $j<br>\n";
                        flush();
                } else {
-                       $sql.=$keys."import)";
-                       $sql.=$vals."$nun)";            
+                       $sql.=$keys."taxzone_id,import)";
+                       $sql.=$vals."0,$nun)";
                        $rc=$db->query($sql);
-                       if (!$rc) echo "Fehler: ".$vals."<br>";
+                       if (!$rc) echo "Fehler: ".$sql."<br>";
                }
                $j++;
        } else {
 
        "customernumber" => "Kundennummer",
        "vendornumber" => "Lieferantennummer",
        "taxnumber" => "Steuernummer",
+       "ustid" => "Umsatzsteuer-ID",
        "account_number" => "Kontonummer",
        "bank_code" => "Bankleitzahl",
        "bank" => "Bankname",
        "branche" => "Branche",
-       "language" => "Sprache (de,en,fr)",
+       //"language" => "Sprache (de,en,fr)",
        "sw" => "Stichwort",
-       "creditlimit" => "Kreditlimit (nnnnnn.nn)",
+       "creditlimit" => "Kreditlimit (nnnnnn.nn)"); /*,
        "hierarchie" => "Hierarchie",
        "potenzial" => "Potenzial",
         "ar" => "Debitorenkonto",
         "ap" => "Kreditorenkonto",
         "matchcode" => "Matchcode",
-       "customernumber2" => "Kundennummer 2");
+       "customernumber2" => "Kundennummer 2"); 
+       Kundenspezifisch */
         
 $shiptos = array(
        "shiptoname" => "Firmenname",
        "partnumber" => "Artikelnummer",
        "description" => "Artikeltext",
        "unit" => "Einheit",
-       "weight" => "Gewicht (kg)",
+       "weight" => "Gewicht in Benutzerdefinition",
        "onhand" => "Lagerbestand",
        "notes" => "Beschreibung",
        "makemodel" => "Hersteller",
        "model" => "Modellbezeichnung",
-       "income_accno_id" => "Erlöskonto",
-       "expense_accno_id" => "Konto Umsatzkosten",
        "bin" => "Lagerort",
        "image" => "Pfad/Dateiname",
        "drawing" => "Pfad/Dateiname",
        "microfiche" => "Pfad/Dateiname",
-       "partsgroup_id" => "Name Warengruppe",
        "listprice" => "Listenpreis",
        "sellprice" => "Verkaufspreis",
        "lastcost" => "letzter EK",
-       "art" => "Ware/Dienstleistung (*/d)");
+       "art" => "Ware/Dienstleistung (*/d), muß vor den Konten kommen",
+       "inventory_accno" => "Bestandskonto",
+       "income_accno" => "Erlöskonto",
+       "expense_accno" => "Konto Umsatzkosten",
+       "obsolete" => "Gesperrt (Y/N)",
+       "lastcost" => "letzer EK-Preis",
+       "rop" => "Mindestbestand",
+       "shop" => "Shopartikel (Y/N)",
+       "assembly" => "Stückliste (Y/N); wird noch nicht unterstützt",
+       "partsgroup" => "Warengruppenbezeichnung",
+       //"income_accno_0" => "?Nummer? für Erlöse Inland",
+       //"income_accno_1" => "?Nummer? für Erlöse EG",
+       //"income_accno_3" => "?Nummer? für Erlöse Ausland",
+       );
        
 $contactscrm = array(
        "customernumber" => "Kundennummer",
        "vendornumber" => "Lieferantennummer",
        "cp_cv_id" => "FirmenID in der db",
        "firma" => "Firmenname",
+       "cp_abteilung" => "Abteilung",
+       "cp_position" => "Position/Hierarchie",
        "cp_greeting" => "Anrede",
        "cp_title" => "Titel",
        "cp_givenname" => "Vorname",
-       "cp_greeting" => "Anrede",
        "cp_name" => "Nachname",
        "cp_email" => "eMail",
        "cp_phone1" => "Telefon 1",
        "cp_phone2" => "Telefon 2",
+       "cp_mobile1" => "Mobiltelefon 1",
+       "cp_mobile2" => "Mobiltelefon 2",
+       "cp_homepage" => "Homepage",
        "cp_street" => "Strasse",
+       "cp_country" => "Land",
        "cp_zipcode" => "PLZ",
        "cp_city" => "Ort",
+       "cp_privatphone" => "Privattelefon",
+       "cp_privatemail" => "private eMail",
        "cp_notes" => "Bemerkungen",
-       "cp_country" => "Land",
        "cp_stichwort1" => "Stichwort(e)",
        "katalog" => "Katalog",
        "inhaber" => "Inhaber",
        "cp_email" => "eMail",
        "cp_phone1" => "Telefon 1",
        "cp_phone2" => "Telefon 2",
+       "cp_mobile1" => "Mobiltelefon 1",
+       "cp_mobile2" => "Mobiltelefon 2",
+       "cp_privatphone" => "Privattelefon",
+       "cp_privatemail" => "private eMail",
+       "cp_homepage" => "Homepage",
        "katalog" => "Katalog",
        "inhaber" => "Inhaber",
        "contact_id" => "Kontakt ID"
        }
 }
 
+function getAllBG($db) {
+       $sql  = "select * from buchungsgruppen order by description";
+       $rs=$db->getAll($sql);
+       return $rs;
+}
+
 class myDB extends DB {
 // Datenbankklasse
 
 
--- /dev/null
+<html>
+<LINK REL="stylesheet" HREF="../css/lx-office-erp.css" TYPE="text/css" TITLE="Lx-Office stylesheet">
+<body>
+<?
+/*
+Warenimport mit Browser nach Lx-Office ERP
+Henry Margies <h.margies@maxina.de>
+Holger Lindemann <hli@lx-system.de>
+*/
+
+/* get login via GET or POST */
+if ($_GET["login"]) {
+       $login=$_GET["login"];
+} else {
+       $login=$_POST["login"];
+};
+
+require ("import_lib.php");
+/* get DB instance */
+$db=new myDB($login);
+
+
+/* just display page or do real import? */
+if ($_POST["ok"]) {
+
+
+require ("parts_import.php");
+
+function ende($nr) {
+       echo "Abbruch: $nr<br>";
+       echo "Fehlende oder falsche Daten.";
+       exit(1);
+}
+
+/* display help */
+if ($_POST["ok"]=="Hilfe") {
+       echo "Importfelder:<br>";
+       echo "Feldname => Bedeutung<br>";
+       foreach($parts as $key=>$val) {
+               echo "$key => $val<br>";
+       }
+       echo "Jeder Artikel muß einer Buchungsgruppe zugeordnet werden. ";
+       echo "Dazu muß entweder in der Maske eine Standardbuchungsgruppe gewählt werden <br>";
+       echo "oder es wird ein gültiges Konto in 'income_accno_id' und 'expense_accno_id' eingegeben. ";
+       echo "Das Programm versucht dann eine passende Buchungsgruppe zu finden.";
+       exit(0);
+};
+
+clearstatcache ();
+
+$test    = $_POST["test"];
+$trenner = ($_POST["trenner"])?$_POST["trenner"]:",";
+$file    = "parts";
+
+/* no data? */
+if (empty($_FILES["Datei"]["name"]))
+       ende (2);
+
+/* copy file */
+if (!move_uploaded_file($_FILES["Datei"]["tmp_name"],$file.".csv")) {
+       echo "Upload von Datei fehlerhaft.";
+       echo $_FILES["Datei"]["error"], "<br>";
+       ende (2);
+} 
+
+/* ??? */
+if (!file_exists("../users/$login.conf")) 
+       ende(3);
+
+/* check if file is really there */
+if (!file_exists("$file.csv")) 
+       ende(5);
+
+/* ??? */
+if (!$db->chkcol($file)) 
+       ende(6);
+
+/* ??? */
+if (!chkUsr($login))
+       ende(4);
+
+/* first check all elements */
+echo "Checking data:<br>";
+$err = import_parts($db, $file, $trenner, $parts, TRUE, FALSE, FALSE,$_POST);
+echo "$err Errors found\n";
+
+
+if ($err!=0)
+       exit(0);
+
+/* just print data or insert it, if test is false */
+import_parts($db, $file, $trenner, $parts, FALSE, !$test, TRUE,$_POST);
+
+} else {
+       $bugrus=getAllBG($db);
+?>
+
+<p class="listtop">Artikelimport für die ERP<p>
+<br>
+<form name="import" method="post" enctype="multipart/form-data" action="partsB.php">
+<input type="hidden" name="MAX_FILE_SIZE" value="2000000">
+<input type="hidden" name="login" value="<?= $login ?>">
+<table>
+<tr><td></td><td><input type="submit" name="ok" value="Hilfe"></td></tr>
+<tr><td>Trennzeichen</td><td><input type="text" size="2" maxlength="1" name="trenner" value=";"></td></tr>
+<tr><td>Test</td><td><input type="checkbox" name="test" value="1">ja</td></tr>
+<tr><td>Art</td><td><input type="Radio" name="ware" value="W">Ware   
+                   <input type="Radio" name="ware" value="D">Dienstleistung
+                   <input type="Radio" name="ware" value="G" checked>gemischt (Spalte 'art' vorhanden)</td></tr>
+<tr><td>Default Bugru<br></td><td><select name="bugru">
+<?     if ($bugrus) foreach ($bugrus as $bg) { ?>
+                       <option value="<?= $bg["id"] ?>"><?= $bg["description"] ?>
+<?     } ?>
+       </select>
+       <input type="radio" name="bugrufix" value="0" checked>nie<br>
+       <input type="radio" name="bugrufix" value="1">für alle Artikel verwenden
+       <input type="radio" name="bugrufix" value="2">für Artikel ohne passende Bugru
+       </td></tr>
+<tr><td>Daten</td><td><input type="file" name="Datei"></td></tr>
+<tr><td></td><td><input type="submit" name="ok" value="Import"></td></tr>
+</table>
+</form>
+<? }; ?>
 
--- /dev/null
+<?
+//Henry Margies <h.margies@maxina.de>
+//Holger Lindemann <hli@lx-system.de>
+
+/**
+ * Returns ID of a partgroup (or adds a new partgroup entry)
+ * \db is the database
+ * \value is the partgroup name
+ * \add if true and partgroup does not exist yet, we will add it automatically
+ * \returns partgroup id or "" in case of an error
+ */
+function getPartsgroupId($db, $value, $add) {
+       
+       $sql="select id from partsgroup where partsgroup = '$value'";
+       $rs=$db->getAll($sql);
+       if (empty($rs[0]["id"]) && $add) {
+               $sql="insert into partsgroup (partsgroup) values ('$value')";
+               $rc=$db->query($sql);
+               if (!$rc)
+                       return "";
+               return getPartsgroupId($db, $value, 0);
+       }
+       return $rs[0]["id"];
+}
+
+function getAccnoId($db, $accno) {
+       $sql = "select id from chart where accno='$accno'";
+       $rs=$db->getAll($sql);
+       return $rs[0]["id"];
+}
+
+function chkPartNumber($db,$number,$check) {
+       if ($number<>"") {
+               $sql = "select * from parts where partnumber = '$number'";
+               $rs=$db->getAll($sql);
+       }
+       //echo $sql; print_r($rs);
+       if ($rs[0]["id"]>0 or $number=="") {
+               if ($check) return "check";
+               $rc=$db->query("BEGIN");
+               $sql = "select  articlenumber from defaults";
+               $rs=$db->getAll($sql);
+               if ($rs[0]["articlenumber"]) {
+                       preg_match("/([^0-9]+)?([0-9]+)([^0-9]+)?/", $rs[0]["articlenumber"] , $regs);
+                       $number=$regs[1].($regs[2]+1).$regs[3];
+               }
+               $sql = "update defaults set articlenumber = '$number'";
+               $rc=$db->query($sql);
+               $rc=$db->query("COMMIT");
+               $sql = "select * from parts where partnumber = '$number'";
+               $rs=$db->getAll($sql);
+               if ($rs[0]["id"]>0) return "";
+       }
+       return $number;
+}
+
+function getBuchungsgruppe($db, $income, $expense) {
+
+       $income_id = getAccnoId($db, $income);
+       $expense_id = getAccnoId($db, $expense);
+       //$accno0_id = getAccnoId($db, $accno0);
+       //$accno1_id = getAccnoId($db, $accno1);
+       //$accno3_id = getAccnoId($db, $accno3);
+
+       $sql  = "select id from buchungsgruppen where ";
+       $sql .= "income_accno_id_0 = $income_id and ";
+       $sql .= "expense_accno_id_0 = $expense_id ";
+       //$sql .= "income_accno_id_0 = '$accno0_id' ";
+       //$sql .= "and income_accno_id_1 = '$accno1_id' ";
+       //$sql .= "and income_accno_id_3 = '$accno3_id'";
+       $rs=$db->getAll($sql);
+       return $rs[0]["id"];
+}
+
+
+function getFromBG($db, $bg_id, $name) {
+       
+       $sql  = "select $name from buchungsgruppen where id='$bg_id'";
+       $rs=$db->getAll($sql);
+       return $rs[0][$name];
+}
+
+function existUnit($db, $value) {
+       $sql="select name from units where name = '$value'";
+       $rs=$db->getAll($sql);
+       if (empty($rs[0]["name"]))
+               return FALSE;
+       return TRUE;
+}
+
+function show($show, $things) {
+       if ($show)
+               echo $things;
+}
+
+function import_parts($db, $file, $trenner, $fields, $check, $insert, $show,$maske) {
+
+       /* field description */
+       $parts_fld = array_keys($fields);
+
+       /* open csv file */
+       $f=fopen("$file.csv","r");
+       
+       /*
+        * read first line with table descriptions
+        */
+       show( $show, "<table border='1'><tr><td>#</td>\n");
+       $infld=fgetcsv($f,1200,$trenner);
+       foreach ($infld as $fld) {
+               $fld = strtolower(trim(strtr($fld,array("\""=>"","'"=>""))));
+               $in_fld[]=$fld;
+               if (in_array(trim($fld),$parts_fld)) {
+                       show( $show, "<td>$fld</td>\n");
+               }
+       }
+
+       $m=0;           /* line */
+       $errors=0;      /* number of errors detected */
+       $income_accno = "";
+       $expense_accno = "";
+       while ( ($zeile=fgetcsv($f,1200,$trenner)) != FALSE) {
+               $i=0;   /* column */
+               $m++;   /* increase line */
+
+               $sql="insert into $file ";
+               $keys="(";
+               $vals=" values (";
+
+               show( $show, "<tr><td>$m</td>\n");
+
+               /* for each column */
+               $dienstleistung=false;
+               $artikel=-1;
+               $partNr=false;
+               foreach($zeile as $data) {
+                       /* check if column will be imported */
+                       if (!in_array(trim($in_fld[$i]),$parts_fld)) {
+                               $i++;
+                               continue;
+                       };
+                       $data=trim($data);
+                       //$data=addslashes($data);
+                       $key=$in_fld[$i];
+                       /* add key and data */
+                       if ($data==false or empty($data) or !$data) {
+                               show( $show, "<td>NULL</td>\n");
+                               $i++;
+                               continue;
+                       }
+
+                       /* special case partsgroup */
+                       if ($key == "partsgroup") {
+
+                               /* get ID of partsgroup or add new 
+                                * partsgroup_id */
+                               $data = getPartsgroupId($db, $data, $insert);
+                               $key  = "partsgroup_id";
+
+                               /* TODO error handling */
+
+                       } else if ($key == "lastcost" || 
+                                  $key == "sellprice") {
+                               
+                               /* convert 0,0 numeric into 0.0 */
+                               $data = str_replace(",", ".", $data);
+
+                       } else if ($key == "partnumber") {
+                               $partNr=true;
+                               $partnumber=chkPartNumber($db,$data,$check);
+                               if ($partnumber=="") {
+                                       show( $show, "<td>NULL</td>\n");
+                                       $i++;
+                                       continue;
+                               } else {
+                                       //$keys.="partnumber, ";
+                                       $data=$partnumber;
+                                       //show( $show, "<td>$partnumber</td>\n");
+                               }
+                       } else if ($key == "description") {
+                               $data=mb_convert_encoding($data,"ISO-8859-15","auto");
+                               $data=addslashes($data);
+                       } else if ($key == "notes") {
+                               $data=mb_convert_encoding($data,"ISO-8859-15","auto");
+                               $data=addslashes($data);
+                       } else if ($key == "unit") {
+                               /* convert stück and Stunde */
+                               if (preg_match("/^st..?ck$/i", $data))
+                                       $data = "Stck";
+                               else if ($data == "Stunde")
+                                       $data = "Std";
+                               /* check if unit exists */
+                               if (!existUnit($db, $data)) {
+                                       echo "Error in line $m: ";
+                                       echo "Einheit <b>$data</b> existiert nicht ";
+                                       echo "Bitte legen Sie diese Einheit an<br>";
+                                       $errors++;
+                               }
+                       } else if ($key == "art") {
+                               if ($maske["ware"]=="G" and strtoupper($data)=="D") { $artikel=false; }
+                               else if ($maske["ware"]=="G") { $artikel=true; };
+                               $i++;
+                               continue;
+                       } else if ($key == "income_accno") {
+                               $income_accno = $data;
+                               $i++;
+                               show( $show, "<td>$data</td>\n");
+                               continue;
+                       } else if ($key == "expense_accno") {
+                               $expense_accno = $data;
+                               $i++;
+                               show( $show, "<td>$data</td>\n");
+                               continue;
+                       }
+                       /* convert JA to Yes */
+                       if ($data == "J" )
+                               $data = "Y";
+
+                       $vals.="'".$data."',";
+                       show( $show, "<td>$data</td>\n");
+                       $keys.=$key.",";
+       
+                       $i++;
+               }
+               if ($artikel==-1) {
+                       if ($maske["ware"]=="D") {  $artikel=false; }
+                       else { $artikel=true; };                        
+               }               
+               if ($maske["bugrufix"]==1) {
+                       $bg = $maske["bugru"];
+               } else {
+                       if ($income_accno<>"" and $expense_accno<>"") {
+                               /* search for buchungsgruppe */
+                               $bg = getBuchungsgruppe($db, $income_accno, $expense_accno);
+                               if ($bg == "" and $maske["bugrufix"]==2 and $maske["bugru"]<>"") {
+                                       $bg = $maske["bugru"];
+                               }
+                       } else if ($maske["bugru"]<>"" and $maske["bugrufix"]==2) {
+                               $bg = $maske["bugru"];
+                       } else {
+                               /* nothing found? user must create one */
+                               echo "Error in line $m: ";
+                               echo "Keine Buchungsgruppe gefunden für <br>";
+                               echo "Erlöse Inland: $income_accno<br>";
+                               echo "Bitte legen Sie eine an oder geben Sie eine vor.<br>";
+                               echo "<br>";
+                               $errors++;
+                       }
+               }
+               if ($bg > 0) {
+                       /* found one, add income_accno_id etc from buchungsgr.
+                        */
+                       $keys.="buchungsgruppen_id, ";
+                       $vals.="'$bg', ";
+                       /* XXX nur bei artikel!!! */
+                       if ($artikel) {
+                               $keys.="inventory_accno_id, ";
+                               $vals.=getFromBG($db, $bg, "inventory_accno_id")." ,";
+                       };
+                       $keys.="income_accno_id, ";
+                       $vals.=getFromBG($db, $bg, "income_accno_id_0")." ,";
+                       $keys.="expense_accno_id,";
+                       $vals.=getFromBG($db, $bg, "expense_accno_id_0")." ,";
+               }
+               if ($partNr==false) {
+                       $partnumber=chkPartNumber($db,"",$check);
+                       if ($partnumber=="") {
+                               show( $show, "<td>NULL</td>\n");
+                               $errors++;
+                       } else {
+                               $keys.="partnumber, ";
+                               $vals.="'$partnumber',";
+                               show( $show, "<td>$partnumber</td>\n");
+                       }
+               } 
+               $sql.=$keys."import)";
+               $sql.=$vals.time().")";         
+               //show( $show, "<td> $sql </td>\n");
+
+               if ($insert) {
+                       show( $show, "<td>");
+                       $db->showErr = TRUE;
+                       $rc=$db->query($sql);
+                       if (!$rc) {
+                               echo "Fehler";
+                               $fehler++;
+                       }
+                       show( $show, "</td>\n");
+               }
+
+               show( $show, "</tr>\n");
+       }
+
+       show( $show, "</table>\n");
+       fclose($f);
+       echo "$m Zeilen bearbeitet. ($fehler : Fehler) ";
+       return $errors;
+}
+
+?>
+
 
        if ($_POST["ok"]=="Hilfe") {
                echo "Importfelder:<br>";
                echo "Feldname => Bedeutung<br>";
-               foreach($contact as $key=>$val) {
+               foreach($shiptos as $key=>$val) {
                        echo "$key => $val<br>";
                }
                exit(0);
 
 # Erstellt die benotigten Symlinks
 
 ln -vsf login.pl admin.pl
-for i in ap ar bp ca cp ct cn dn gl ic ir is menu oe pe rc rp datev licenses fa ustva menunew common; do
+for i in ap ar bp ca cp ct cn dn gl ic ir is menu oe pe rc rp datev licenses fa ustva menunew common menuv3; do
   ln -vsf am.pl $i.pl
 done
 
 
 [System--Import CSV--Shipto]
 module=lxo-import/shiptoB.php
 
+[System--Import CSV--Parts]
+module=lxo-import/partsB.php
+
 #[System--SIC]
 #module=menu.pl
 #action=acc_menu
 #module=am.pl
 #action=list_sic
 
-[System--HTML Templates]
-module=menu.pl
-action=acc_menu
-target=acc_menu
-submenu=1
-
-[System--HTML Templates--Income Statement]
-module=am.pl
-action=display_form
-file=templates=income_statement.html
-
-[System--HTML Templates--BWA]
-module=am.pl
-action=display_form
-file=templates=bwa.html
-
-[System--HTML Templates--Balance Sheet]
-module=am.pl
-action=display_form
-file=templates=balance_sheet.html
-
-[System--HTML Templates--Invoice]
-module=am.pl
-action=display_form
-file=templates=invoice.html
-
-[System--HTML Templates--Packing List]
-module=am.pl
-action=display_form
-file=templates=packing_list.html
-
-[System--HTML Templates--Sales Order]
-module=am.pl
-action=display_form
-file=templates=sales_order.html
-
-[System--HTML Templates--Purchase Order]
-module=am.pl
-action=display_form
-file=templates=purchase_order.html
-
-[System--HTML Templates--Statement]
-module=am.pl
-action=display_form
-file=templates=statement.html
-
-[System--HTML Templates--Quotation]
-module=am.pl
-action=display_form
-file=templates=sales_quotation.html
-
-[System--HTML Templates--RFQ]
-module=am.pl
-action=display_form
-file=templates=request_quotation.html
-
-[System--HTML Templates--UStVA]
-module=am.pl
-action=display_form
-file=templates=ustva.html
-
-[System--LaTeX Templates]
-module=menu.pl
-action=acc_menu
-target=acc_menu
-submenu=1
-
-[System--LaTeX Templates--Invoice]
-module=am.pl
-action=display_form
-file=templates=invoice.tex
-
-[System--LaTeX Templates--Packing List]
-module=am.pl
-action=display_form
-file=templates=packing_list.tex
-
-[System--LaTeX Templates--Sales Order]
-module=am.pl
-action=display_form
-file=templates=sales_order.tex
-
-[System--LaTeX Templates--Purchase Order]
-module=am.pl
-action=display_form
-file=templates=purchase_order.tex
-
-[System--LaTeX Templates--Statement]
-module=am.pl
-action=display_form
-file=templates=statement.tex
-
-[System--LaTeX Templates--Check]
-module=am.pl
-action=display_form
-file=templates=check.tex
-
-[System--LaTeX Templates--Receipt]
-module=am.pl
-action=display_form
-file=templates=receipt.tex
-
-[System--LaTeX Templates--Quotation]
-module=am.pl
-action=display_form
-file=templates=sales_quotation.tex
-
-[System--LaTeX Templates--RFQ]
-module=am.pl
-action=display_form
-file=templates=request_quotation.tex
-
-[System--LaTeX Templates--UStVA 2006]
-module=am.pl
-action=display_form
-file=templates=ustva-2006.tex
-
-[System--LaTeX Templates--UStVA 2005]
-module=am.pl
-action=display_form
-file=templates=ustva-2005.tex
-
-[System--LaTeX Templates--UStVA 2004]
-module=am.pl
-action=display_form
-file=templates=ustva-2004.tex
-
 [System--Stylesheet]
 module=am.pl
 action=display_stylesheet
 
--- /dev/null
+#!/usr/bin/perl
+
+BEGIN {
+  if (! -d "bin" || ! -d "SL") {
+    print("This tool must be run from the Lx-Office ERP base directory.\n");
+    exit(1);
+  }
+}
+
+use DBI;
+use Data::Dumper;
+use Getopt::Long;
+
+use SL::LXDebug;
+
+$lxdebug = LXDebug->new();
+
+use SL::Form;
+use SL::DBUpgrade2;
+
+#######
+#######
+#######
+
+sub show_help {
+  print("dbupgrade2_tool.pl [--list] [--tree] [--rtree] [--graphviz]\n" .
+        "                   [--nodepds] [--help]\n");
+}
+
+sub calc_rev_depends {
+  map({ $_->{"rev_depends"} = []; } values(%{$controls}));
+  foreach my $control (values(%{$controls})) {
+    map({ push(@{$controls->{$_}{"rev_depends"}}, $control->{"tag"}) }
+        @{$control->{"depends"}});
+  }
+}
+
+sub dump_list {
+  my @sorted_controls = sort_dbupdate_controls($controls);
+
+  print("LIST VIEW\n\n");
+  print("number tag depth priority\n");
+  $i = 0;
+  foreach (@sorted_controls) {
+    print("$i $_->{tag} $_->{depth} $_->{priority}\n");
+    $i++;
+  }
+
+  print("\n");
+}
+
+sub dump_node {
+  my ($tag, $depth) = @_;
+
+  print(" " x $depth . $tag . "\n");
+
+  my $c = $controls->{$tag};
+  my $num = scalar(@{$c->{"depends"}});
+  for (my $i = 0; $i < $num; $i++) {
+    dump_node($c->{"depends"}[$i], $depth + 1);
+  }
+}
+
+sub dump_tree {
+  print("TREE VIEW\n\n");
+
+  calc_rev_depends();
+
+  my @sorted_controls = sort_dbupdate_controls($controls);
+
+  foreach my $control (@sorted_controls) {
+    dump_node($control->{"tag"}, "") unless (@{$control->{"rev_depends"}});
+  }
+
+  print("\n");
+}
+
+sub dump_node_reverse {
+  my ($tag, $depth) = @_;
+
+  print(" " x $depth . $tag . "\n");
+
+  my $c = $controls->{$tag};
+  my $num = scalar(@{$c->{"rev_depends"}});
+  for (my $i = 0; $i < $num; $i++) {
+    dump_node_reverse($c->{"rev_depends"}[$i], $depth + 1);
+  }
+}
+
+sub dump_tree_reverse {
+  print("REVERSE TREE VIEW\n\n");
+
+  calc_rev_depends();
+
+  my @sorted_controls = sort_dbupdate_controls($controls);
+
+  foreach my $control (@sorted_controls) {
+    last if ($control->{"depth"} > 1);
+    dump_node_reverse($control->{"tag"}, "");
+  }
+
+  print("\n");
+}
+
+sub dump_graphviz {
+  print("GRAPHVIZ POSTCRIPT\n\n");
+  print("Output will be written to db_dependencies.ps\n");
+  $dot = "|dot -Tps ";
+  open(OUT, "${dot}> db_dependencies.ps");
+  print(OUT
+        "digraph db_dependencies {\n" .
+        "node [shape=box];\n");
+  my %ranks;
+  foreach my $c (values(%{$controls})) {
+    $ranks{$c->{"depth"}} = [] unless ($ranks{$c->{"depth"}});
+    push(@{$ranks{$c->{"depth"}}}, $c->{"tag"});
+  }
+  foreach (sort(keys(%ranks))) {
+    print(OUT "{ rank = same; " .
+          join("", map({ '"' . $_ . '"; ' } @{$ranks{$_}})) .
+          " }\n");
+  }
+  foreach my $c (values(%{$controls})) {
+    print(OUT "$c->{tag};\n");
+    foreach my $d (@{$c->{"depends"}}) {
+      print(OUT "$c->{tag} -> $d;\n");
+    }
+  }
+  print(OUT "}\n");
+  close(OUT);
+}
+
+sub dump_nodeps {
+  calc_rev_depends();
+
+  print("SCRIPTS NO OTHER SCRIPTS DEPEND ON\n\n" .
+        join("\n",
+             map({ $_->{"tag"} }
+                 grep({ !@{$_->{"rev_depends"}} }
+                      values(%{$controls})))) .
+        "\n\n");
+}
+
+#######
+#######
+#######
+
+eval { require "lx-erp.conf"; };
+
+$form = Form->new();
+$locale = Locale->new("de", "login");
+
+#######
+#######
+#######
+
+my ($opt_list, $opt_tree, $opt_rtree, $opt_nodeps, $opt_graphviz, $opt_help);
+
+GetOptions("list" => \$opt_list,
+           "tree" => \$opt_tree,
+           "rtree" => \$opt_rtree,
+           "nodeps" => \$opt_nodeps,
+           "graphviz" => \$opt_graphviz,
+           "help" => \$opt_help,
+  );
+
+if ($opt_help) {
+  show_help();
+  exit(0);
+}
+
+$controls = parse_dbupdate_controls($form, "Pg");
+
+if ($opt_list) {
+  dump_list();
+}
+
+if ($opt_tree) {
+  dump_tree();
+}
+
+if ($opt_rtree) {
+  dump_tree_reverse();
+}
+
+if ($opt_graphviz) {
+  dump_graphviz();
+}
+
+if ($opt_nodeps) {
+  dump_nodeps();
+}
 
--- /dev/null
+#!/usr/bin/perl -w
+=head1 NAME
+
+find-use
+
+=head1 EXAMPLE
+
+ ~/ledgersmb # utils/devel/find-use
+ 0.000000 : HTML::Entities
+ 0.000000 : Locale::Maketext::Lexicon
+ 0.000000 : Module::Build
+ ...
+
+=head1 EXPLINATION
+
+This util is useful for package builders to identify all the CPAN dependencies we've made.  It required Module::CoreList (which is core, but is not yet in any stable
+release of perl)  to determine if a module is distributed with perl or not.  The output reports which version of perl the module is in.  If it reports 0.000000, then the
+module is not in core perl, and needs to be installed before Lx-Office will operate.
+
+=head1 AUTHOR
+
+http://www.ledgersmb.org/ - The LedgerSMB team
+
+=head1 LICENSE
+
+Distributed under the terms of the GNU General Public License v2.
+=cut
+
+
+use strict;
+use warnings;
+
+open GREP, "grep -r '^use ' . |";
+use Module::CoreList;
+
+my %uselines;
+while(<GREP>) { 
+       next if /SL::/;
+       next if /LX::/;
+       next if /use warnings/;
+       next if /use strict/;
+       next if /use vars/;
+       chomp;
+       my ($file, $useline) = m/^([^:]+):use\s(.*?)$/;
+       $uselines{$useline}||=[];
+       push @{$uselines{$useline}}, $file;
+}
+
+my %modules;
+foreach my $useline (keys %uselines) {
+
+       my ($module) = grep { $_ } $useline =~ /(?:base ['"]([a-z:]+)|([a-z:]+)(?:\s|;))/i;
+       my $version = Module::CoreList->first_release($module);
+       $modules{$module} = $version||0;
+}
+
+foreach my $mod (sort { $modules{$a} == 0 ? -1 : $modules{$b} == 0 ? 1 : 0  or $a cmp $b } keys %modules) { 
+       printf "%2.6f : %s\n", $modules{$mod}, $mod;
+}
+
 
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4673', 'Reisek.Untern.m.Vorsteuerabzug (öffentl.Verkehrsm.', 'A', 'E', 'AP_amount', '4673', 8, NULL, 15, NULL, 18, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4674', 'Reisekosten Untern.Verpflegungsmehr', 'A', 'E', 'AP_amount', '4674', 0, NULL, 15, NULL, 18, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4676', 'Reisekosten Untern.Übernachtungsauf', 'A', 'E', 'AP_amount', '4676', 0, NULL, 15, NULL, 18, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4700', 'Kosten der Warenabgabe', 'A', 'E', 'AP_amount:IC_cogs', '4700', 16, NULL, NULL, NULL, 24, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4710', 'Verpackungsmaterial', 'A', 'E', 'AP_amount:IC_cogs', '4710', 16, NULL, NULL, NULL, 24, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4730', 'Ausgangsfracht', 'A', 'E', 'AP_amount:IC_cogs', '4730', 16, NULL, NULL, NULL, 24, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4750', 'Transportversicherung', 'A', 'E', 'AP_amount:IC_cogs:IC_expense', '4750', 16, NULL, NULL, NULL, 24, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4760', 'Verkaufsprovision', 'A', 'E', 'AP_amount:IC_expense', '4760', 16, NULL, NULL, NULL, 24, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4780', 'Fremdarbeiten', 'A', 'E', 'AP_amount:IC_expense', '4780', 16, NULL, NULL, NULL, 24, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4700', 'Kosten der Warenabgabe', 'A', 'E', 'AP_amount:IC_cogs', '4700', 0, NULL, NULL, NULL, 24, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4710', 'Verpackungsmaterial', 'A', 'E', 'AP_amount:IC_cogs', '4710', 0, NULL, NULL, NULL, 24, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4730', 'Ausgangsfracht', 'A', 'E', 'AP_amount:IC_cogs', '4730', 0, NULL, NULL, NULL, 24, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4750', 'Transportversicherung', 'A', 'E', 'AP_amount:IC_cogs:IC_expense', '4750', 0, NULL, NULL, NULL, 24, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4760', 'Verkaufsprovision', 'A', 'E', 'AP_amount:IC_expense', '4760', 0, NULL, NULL, NULL, 24, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4780', 'Fremdarbeiten', 'A', 'E', 'AP_amount:IC_expense', '4780', 0, NULL, NULL, NULL, 24, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4790', 'Aufwand für Gewährleistungen', 'A', 'E', 'AP_amount:IC_expense', '4790', 0, NULL, 20, NULL, 24, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4800', 'Rep.u.Instandhaltungen v.techn.Anlagen u.Maschinen', 'A', 'E', 'AP_amount', '4800', 9, NULL, 18, NULL, 19, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4806', 'Wartungskosten für Hard-u.Software', 'A', 'E', 'AP_amount:IC_expense', '4806', 9, NULL, 18, NULL, 19, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4809', 'Sonstige Reparaturen u.Instandhalt.', 'A', 'E', 'AP_amount', '4809', 9, NULL, NULL, NULL, 19, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4810', 'Mietleasing', 'A', 'E', 'AP_amount', '4810', 0, NULL, 20, NULL, 24, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4815', 'Kaufleasing', 'A', 'E', 'AP_amount', '4815', 0, NULL, 20, NULL, 24, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4822', 'Abschreibungen a.immat.Vermögensgeg', 'A', 'E', '', '4822', 17, NULL, NULL, NULL, 25, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4824', 'Abschreibung a.d.Geschäft-o.Firmenw', 'A', 'E', '', '4824', 17, NULL, NULL, NULL, 25, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4840', 'Außerplanmäßig Abschr.a.Sachanlagen', 'A', 'E', '', '4840', 17, NULL, NULL, NULL, 25, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4855', 'Sofortabschreibung GWG', 'A', 'E', 'AP_amount', '4855', 17, NULL, NULL, NULL, 26, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4860', 'Abschreibungen auf aktivierte GWG', 'A', 'E', '', '4860', 17, NULL, NULL, NULL, 25, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4822', 'Abschreibungen a.immat.Vermögensgeg', 'A', 'E', '', '4822', 0, NULL, NULL, NULL, 25, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4824', 'Abschreibung a.d.Geschäft-o.Firmenw', 'A', 'E', '', '4824', 0, NULL, NULL, NULL, 25, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4840', 'Außerplanmäßig Abschr.a.Sachanlagen', 'A', 'E', '', '4840', 0, NULL, NULL, NULL, 25, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4855', 'Sofortabschreibung GWG', 'A', 'E', 'AP_amount', '4855', 0, NULL, NULL, NULL, 26, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4860', 'Abschreibungen auf aktivierte GWG', 'A', 'E', '', '4860', 0, NULL, NULL, NULL, 25, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4900', 'Sonstige betriebliche Aufwendungen', 'A', 'E', 'AP_amount', '4900', 9, NULL, 20, NULL, 24, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4905', 'Sons.Aufw.betriebl. und regelmäßig', 'A', 'E', 'AP_amount', '4905', 9, NULL, NULL, NULL, 24, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4909', 'Fremdleistungen', 'A', 'E', 'AP_amount', '4909', 0, NULL, 20, NULL, 24, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('8935', 'Unentgeltl.Zuwend.v.Gegens. 16% Ust', 'A', 'I', 'AR_amount', '8935', 3, 51, NULL, NULL, 3, TRUE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('8950', 'Nicht steuerbare Umsätze', 'A', 'I', '', '8950', 0, NULL, 5, NULL, 1, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('8955', 'Umsatzsteuervergütungen', 'A', 'I', '', '8955', 0, NULL, NULL, NULL, 7, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9000', 'Saldenverträge,Sachkonten', 'A', 'A', '', '9000', 0, NULL, NULL, NULL, NULL, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9008', 'Saldenverträge,Debitoren', 'A', 'A', '', '9008', 0, NULL, NULL, NULL, NULL, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9009', 'Saldenverträge,Kreditoren', 'A', 'L', '', '9009', 0, NULL, NULL, NULL, NULL, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9000', 'Saldenvorträge,Sachkonten', 'A', 'A', '', '9000', 0, NULL, NULL, NULL, NULL, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9008', 'Saldenvorträge,Debitoren', 'A', 'A', '', '9008', 0, NULL, NULL, NULL, NULL, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9009', 'Saldenvorträge,Kreditoren', 'A', 'L', '', '9009', 0, NULL, NULL, NULL, NULL, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9090', 'Summenvortragskonto', 'A', 'A', '', '9090', 0, NULL, NULL, NULL, NULL, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('8400', 'Erlöse 16% USt.', 'A', 'I', 'AR_amount:IC_sale:IC_income', '8400', 3, 51, 1, NULL, 1, TRUE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('8800', 'Erlöse aus Anlagenverkäufen', 'A', 'I', 'AR_amount', '8800', 3, 51, NULL, NULL, 1, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('0650', 'Vblk.geg.Kreditinst.- Restlaufzeit grösser als 5 Jahre', 'A', 'A', '', '0650', 0, NULL, NULL, NULL, NULL, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4510', 'Kfz-Steuer', 'A', 'E', 'AP_amount', '4510', 0, NULL, 19, NULL, 15, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('4520', 'Kfz-Versicherungen', 'A', 'E', 'AP_amount', '4520', 0, NULL, 14, NULL, 16, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1771', 'Umsatzsteuer 7%', 'A', 'I', 'AR_tax:IC_taxpart:IC_taxservice:CT_tax', '1771', 861, NULL, NULL, NULL, 5, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1775', 'Umsatzsteuer 16%', 'A', 'I', 'AR_tax:IC_taxpart:IC_taxservice:CT_tax', '1775', 511, NULL, NULL, NULL, 6, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1771', 'Umsatzsteuer 7%', 'A', 'I', 'AR_tax:IC_taxpart:IC_taxservice:CT_tax', '1771', 0, NULL, NULL, NULL, 5, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1775', 'Umsatzsteuer 16%', 'A', 'I', 'AR_tax:IC_taxpart:IC_taxservice:CT_tax', '1775', 0, NULL, NULL, NULL, 6, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1767', 'Im anderen EG-Staat steuerpfl. Lieferung', 'A', ' ', '', '1767', 10, NULL, 0, NULL, NULL, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('0853', 'Satzungsm.Rücklagen 0% Vorbelast.(st.Einlagekto.)', 'A', 'Q', '', '0853', 0, NULL, NULL, NULL, NULL, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1607', 'Vblk.a.LuL ohne Vorsteuer (EÜR)', 'A', 'L', 'AP', '1607', 0, NULL, NULL, NULL, NULL, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('8922', 'Verwend.f.Gegenst.f.Zwecke außerh.d.Untern.16%USt(Telefonnutzung)', 'A', 'I', '', '8922', 0, 0, 5, NULL, 3, TRUE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1000', 'Kasse', 'A', 'A', 'AR_paid:AP_paid', '1000', 0, NULL, NULL, NULL, NULL, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1572', 'Steuerpflicht. EG-Erwerb 7%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice', '1572', 0, 61, NULL, NULL, 27, FALSE);
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1571', 'Abziebare Vorsteuer 7%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax', '1570', 0, 66, NULL, NULL, 27, FALSE);
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1571', 'Abziehbare Vorsteuer 7%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax', '1570', 0, 66, NULL, NULL, 27, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1573', 'Steuerpflicht. EG-Erwerb 16%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice', '1573', 0, 61, NULL, NULL, 27, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1575', 'Abziehbare Vorsteuer 16%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax', '1570', 0, 66, NULL, NULL, 27, FALSE);
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1772', 'Steuerpflicht. EG-Lieferungen 7%', 'A', 'I', 'AR_tax:IC_taxpart:IC_taxservice', '1772', 0, NULL, NULL, NULL, 6, FALSE);
 
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1249', 'Pauschalwertbe.z.Ford.ueb1J.', 'A', 'E', '', '1249', 0, NULL, 31, NULL, NULL, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1370', 'Durchlaufende Posten', 'A', 'A', '', '1370', 0, NULL, NULL, NULL, NULL, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1374', 'Fremdgeld', 'A', 'A', '', '1374', 0, NULL, NULL, NULL, NULL, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1401', 'Abziebare Vorsteuer 7%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax', '1401', 0, 66, NULL, NULL, 27, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1401', 'Abziehbare Vorsteuer 7%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax', '1401', 0, 66, NULL, NULL, 27, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1402', 'Abziehbare Vorsteuer aus EG-Erwerb 7%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice', '1402', 0, 61, NULL, NULL, 27, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1403', 'Abziehbare Vorsteuer aus EG-Erwerb 16%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice', '1403', 0, 61, NULL, NULL, 27, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('1405', 'Abziehbare Vorsteuer 16%', 'A', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax', '1405', 0, 66, NULL, NULL, 27, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6120', 'Beiträge zur Berufsgenossenschaft', 'A', 'E', '', '6120', 0, NULL, 10, NULL, 10, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6130', 'Freiwillig soziale Aufwendungen lohnsteuerfrei', 'A', 'E', '', '6130', 0, NULL, 10, NULL, 10, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6147', 'Pauschale Lohnsteuer auf sonst.Bezüge(z.B.Direktversicherung', 'A', 'E', '', '6147', 0, NULL, 10, NULL, 9, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6200', 'Abschreibungen a.immat.Vermögensgeg', 'A', 'E', '', '6200', 17, NULL, NULL, NULL, 25, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6205', 'Abschreibung a.d.Geschäft-o.Firmenw', 'A', 'E', '', '6205', 17, NULL, NULL, NULL, 25, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6200', 'Abschreibungen a.immat.Vermögensgeg', 'A', 'E', '', '6200', 0, NULL, NULL, NULL, 25, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6205', 'Abschreibung a.d.Geschäft-o.Firmenw', 'A', 'E', '', '6205', 0, NULL, NULL, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6210', 'Außerplan.AfA a.immat.Vermögensgeg.', 'A', 'E', '', '6210', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6221', 'Abschreibung auf Gebäude', 'A', 'E', '', '6221', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6220', 'Abschreibungen auf Sachanlagen (o.Kfz u.Geb.)', 'A', 'E', '', '6220', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6222', 'Abschreibungen auf Kfz', 'A', 'E', '', '6222', 0, NULL, 17, NULL, 25, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6230', 'Außerplanmäßig Abschr.a.Sachanlagen', 'A', 'E', '', '6230', 17, NULL, NULL, NULL, 25, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6230', 'Außerplanmäßig Abschr.a.Sachanlagen', 'A', 'E', '', '6230', 0, NULL, NULL, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6231', 'Absetzung f.außergew.techn.u.wirtschaftl.AfA bei Gebäuden', 'A', 'E', '', '6231', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6232', 'Absetzung f.außergew.techn.u.wirtschaftl.AfA des Kfz', 'A', 'E', '', '6232', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6233', 'Absetzung f.außergew.techn.u.wirtschaftl.AfA sonst.WG', 'A', 'E', '', '6233', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6241', 'Sonderabschreibung nach §7g(1)u.(2)EStG (ohne Kfz)', 'A', 'E', '', '6241', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6242', 'Sonderabschreibung n.§7g(1)u.(2)EStG (für Kfz)', 'A', 'E', '', '6242', 0, NULL, 17, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6250', 'Kaufleasing', 'A', 'E', 'AP_amount', '6250', 0, NULL, 20, NULL, 24, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6260', 'Sofortabschreibung GWG', 'A', 'E', 'AP_amount', '6260', 17, NULL, NULL, NULL, 26, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6262', 'Abschreibungen auf aktivierte GWG', 'A', 'E', '', '6262', 17, NULL, NULL, NULL, 25, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6260', 'Sofortabschreibung GWG', 'A', 'E', 'AP_amount', '6260', 0, NULL, NULL, NULL, 26, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6262', 'Abschreibungen auf aktivierte GWG', 'A', 'E', '', '6262', 0, NULL, NULL, NULL, 25, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6270', 'Abschreibungen auf Finanzanlagen', 'A', 'E', '', '6270', NULL, NULL, NULL, NULL, NULL, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6275', 'Abschr.a.Wertp.d.Umlaufvermögens', 'A', 'E', '', '6275', 0, NULL, 17, NULL, NULL, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6280', 'Forderungsverlust-übliche Höhe', 'A', 'E', '', '6280', 0, NULL, 20, NULL, NULL, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6680', 'Reisekosten Untern.Übernachtungsauf', 'A', 'E', 'AP_amount', '6680', 0, NULL, 15, NULL, 18, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6688', 'Fahrten zw.Wohn.und Arbeitsstätte (nicht abziehb.Teil)', 'A', 'E', '', '6688', 0, NULL, NULL, NULL, 18, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6689', 'Fahrten zw.Wohn.-und Arbeitsstätte (Haben)', 'A', 'E', '', '6689', 0, NULL, NULL, NULL, 18, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6700', 'Kosten der Warenabgabe', 'A', 'E', 'AP_amount:IC_cogs', '6700', 16, NULL, NULL, NULL, 24, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6710', 'Verpackungsmaterial', 'A', 'E', 'AP_amount:IC_cogs', '6710', 16, NULL, NULL, NULL, 24, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6740', 'Ausgangsfracht', 'A', 'E', 'AP_amount:IC_cogs', '6740', 16, NULL, NULL, NULL, 24, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6760', 'Transportversicherung', 'A', 'E', 'AP_amount:IC_cogs:IC_expense', '6760', 16, NULL, NULL, NULL, 24, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6770', 'Verkaufsprovision', 'A', 'E', 'AP_amount:IC_expense', '6770', 16, NULL, NULL, NULL, 24, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6780', 'Fremdarbeiten', 'A', 'E', 'AP_amount:IC_expense', '6780', 16, NULL, NULL, NULL, 24, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6700', 'Kosten der Warenabgabe', 'A', 'E', 'AP_amount:IC_cogs', '6700', 0, NULL, NULL, NULL, 24, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6710', 'Verpackungsmaterial', 'A', 'E', 'AP_amount:IC_cogs', '6710', 0, NULL, NULL, NULL, 24, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6740', 'Ausgangsfracht', 'A', 'E', 'AP_amount:IC_cogs', '6740', 0, NULL, NULL, NULL, 24, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6760', 'Transportversicherung', 'A', 'E', 'AP_amount:IC_cogs:IC_expense', '6760', 0, NULL, NULL, NULL, 24, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6770', 'Verkaufsprovision', 'A', 'E', 'AP_amount:IC_expense', '6770', 0, NULL, NULL, NULL, 24, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6780', 'Fremdarbeiten', 'A', 'E', 'AP_amount:IC_expense', '6780', 0, NULL, NULL, NULL, 24, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6790', 'Aufwand für Gewährleistungen', 'A', 'E', 'AP_amount:IC_expense', '6790', 0, NULL, 20, NULL, 24, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6800', 'Porto', 'A', 'E', 'AP_amount', '6800', 0, NULL, 20, NULL, 23, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('6805', 'Telefon', 'A', 'E', 'AP_amount', '6805', 9, NULL, 20, NULL, 23, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('7745', 'Entnahmen a.satzungsmäßigen Rücklagen', 'A', 'E', '', '7745', 0, NULL, NULL, NULL, NULL, FALSE);\r
 \r
 \r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9000', 'Saldenverträge,Sachkonten', 'A', 'A', '', '9000', 0, NULL, NULL, NULL, NULL, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9008', 'Saldenverträge,Debitoren', 'A', 'A', '', '9008', 0, NULL, NULL, NULL, NULL, FALSE);\r
-INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9009', 'Saldenverträge,Kreditoren', 'A', 'L', '', '9009', 0, NULL, NULL, NULL, NULL, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9000', 'Saldenvorträge,Sachkonten', 'A', 'A', '', '9000', 0, NULL, NULL, NULL, NULL, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9008', 'Saldenvorträge,Debitoren', 'A', 'A', '', '9008', 0, NULL, NULL, NULL, NULL, FALSE);\r
+INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9009', 'Saldenvorträge,Kreditoren', 'A', 'L', '', '9009', 0, NULL, NULL, NULL, NULL, FALSE);\r
 INSERT INTO chart (accno, description, charttype, category, link, gifi_accno, taxkey_id, pos_ustva, pos_bwa, pos_bilanz, pos_eur, datevautomatik) VALUES ('9090', 'Summenvortragskonto', 'A', 'A', '', '9090', 0, NULL, NULL, NULL, NULL, FALSE);\r
 \r
 \r
 
 
 die("This script cannot be run from the command line.") unless ($main::form);
 
-use SL::AM;
-
 sub mydberror {
   my ($msg) = @_;
   die($dbup_locale->text("Database update error:") .
   return 2;
 }
 
+sub get_base_unit {
+  my ($units, $unit_name, $factor) = @_;
+
+  $factor = 1 unless ($factor);
+
+  my $unit = $units->{$unit_name};
+
+  if (!defined($unit) || !$unit->{"base_unit"} ||
+      ($unit_name eq $unit->{"base_unit"})) {
+    return ($unit_name, $factor);
+  }
+
+  return get_base_unit($units, $unit->{"base_unit"}, $factor * $unit->{"factor"});
+}
+
+sub retrieve_units {
+  my ($myconfig, $form, $type, $prefix) = @_;
+
+  my $query = "SELECT *, base_unit AS original_base_unit FROM units";
+  my @values;
+  if ($type) {
+    $query .= " WHERE (type = ?)";
+    @values = ($type);
+  }
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute(@values) || $form->dberror($query . " (" . join(", ", @values) . ")");
+
+  my $units = {};
+  while (my $ref = $sth->fetchrow_hashref()) {
+    $units->{$ref->{"name"}} = $ref;
+  }
+  $sth->finish();
+
+  my $query_lang = "SELECT id, template_code FROM language ORDER BY description";
+  $sth = $dbh->prepare($query_lang);
+  $sth->execute() || $form->dberror($query_lang);
+  my @languages;
+  while ($ref = $sth->fetchrow_hashref()) {
+    push(@languages, $ref);
+  }
+  $sth->finish();
+
+  foreach my $unit (values(%{$units})) {
+    ($unit->{"${prefix}base_unit"}, $unit->{"${prefix}factor"}) = get_base_unit($units, $unit->{"name"});
+  }
+
+  return $units;
+}
+
+sub unit_select_data {
+  my ($units, $selected, $empty_entry) = @_;
+
+  my $select = [];
+
+  if ($empty_entry) {
+    push(@{$select}, { "name" => "", "base_unit" => "", "factor" => "", "selected" => "" });
+  }
+
+  foreach my $unit (sort({ lc($a) cmp lc($b) } keys(%{$units}))) {
+    push(@{$select}, { "name" => $unit,
+                       "base_unit" => $units->{$unit}->{"base_unit"},
+                       "factor" => $units->{$unit}->{"factor"},
+                       "selected" => ($unit eq $selected) ? "selected" : "" });
+  }
+
+  return $select;
+}
+
 sub update_units_add_unit {
   my $form = $main::form;
 
 
   return myshowerror($dbup_locale->text("The name is missing."))
     if ($form->{"new_name"} eq "");
-  my $units = AM->retrieve_units(\%dbup_myconfig, $form);
+  my $units = retrieve_units(\%dbup_myconfig, $form);
   return myshowerror($dbup_locale->text("A unit with this name does already exist."))
     if ($units->{$form->{"new_name"}});
-  $units = AM->retrieve_units(\%dbup_myconfig, $form, $form->{"unit_type"});
+  $units = retrieve_units(\%dbup_myconfig, $form, $form->{"unit_type"});
 
   my ($base_unit, $factor);
   if ($form->{"new_base_unit"}) {
   }
 
   if (scalar(keys(%unknown_dimension_units)) != 0) {
-    my $units = AM->retrieve_units(\%dbup_myconfig, $form, "dimension");
-    my $ddbox = AM->unit_select_data($units, undef, 1);
+    my $units = retrieve_units(\%dbup_myconfig, $form, "dimension");
+    my $ddbox = unit_select_data($units, undef, 1);
 
     my @unknown_parts;
     map({ push(@unknown_parts, { "name" => $_, "NEW_UNITS" => $ddbox }); }
   }
 
   if (scalar(keys(%unknown_service_units)) != 0) {
-    my $units = AM->retrieve_units(\%dbup_myconfig, $form, "service");
-    my $ddbox = AM->unit_select_data($units, undef, 1);
+    my $units = retrieve_units(\%dbup_myconfig, $form, "service");
+    my $ddbox = unit_select_data($units, undef, 1);
 
     my @unknown_services;
     map({ push(@unknown_services, { "name" => $_, "NEW_UNITS" => $ddbox }); }
   my ($has_unassigned) = $dbh->selectrow_array($query);
 
   if ($has_unassigned) {
-    my $dimension_units = AM->retrieve_units(\%dbup_myconfig, $form,
+    my $dimension_units = retrieve_units(\%dbup_myconfig, $form,
                                              "dimension");
-    my $dimension_ddbox = AM->unit_select_data($dimension_units);
+    my $dimension_ddbox = unit_select_data($dimension_units);
 
-    my $service_units = AM->retrieve_units(\%dbup_myconfig, $form, "service");
-    my $service_ddbox = AM->unit_select_data($service_units);
+    my $service_units = retrieve_units(\%dbup_myconfig, $form, "service");
+    my $service_ddbox = unit_select_data($service_units);
 
     print($form->parse_html_template("dbupgrade/units_set_default",
                                      { "DIMENSION_DDBOX" => $dimension_ddbox,
 
+++ /dev/null
-update tax set id=0 WHERE taxkey=0;
 
+++ /dev/null
-UPDATE taxkeys SET tax_id = 0 WHERE taxkey_id = 0;
 
--- /dev/null
+Bitte lesen Sie die Datei doc/sql-upgrade-dateien.txt, bevor
+Sie hier Dateien anlegen.
+
 
--- /dev/null
+-- @tag: chart_names
+-- @description: Behebt ein paar Schreibfehler in Kontennamen in den Kontenramen SKR03 und SKR04.
+-- @depends:
+UPDATE chart
+  SET description = replace(description, 'Saldenverträge', 'Saldenvorträge')
+  WHERE
+    ((SELECT coa FROM defaults) IN ('Germany-DATEV-SKR03EU', 'Germany-DATEV-SKR04EU')) AND
+    (description LIKE 'Saldenverträge%');
+UPDATE chart
+  SET description = replace(description, 'Abziebare', 'Abziehbare')
+  WHERE
+    ((SELECT coa FROM defaults) IN ('Germany-DATEV-SKR03EU', 'Germany-DATEV-SKR04EU')) AND
+    (description LIKE 'Abziehbare%');
 
--- /dev/null
+-- @tag: customer_vendor_ustid_length
+-- @description: Setzt das Feld "ustid" in den Tabellen "customer" und "vendor" auf 14 Zeichen: zwei Zeichen Länderkürzel und bis zu zwölf Zeichen für die Nummer.
+-- @depends:
+ALTER TABLE customer ADD COLUMN tmp varchar(14);
+UPDATE customer SET tmp = ustid;
+ALTER TABLE customer DROP COLUMN ustid;
+ALTER TABLE customer RENAME tmp TO ustid;
+
+ALTER TABLE vendor ADD COLUMN tmp varchar(14);
+UPDATE vendor SET tmp = ustid;
+ALTER TABLE vendor DROP COLUMN ustid;
+ALTER TABLE vendor RENAME tmp TO ustid;
 
--- /dev/null
+-- @tag: invalid_taxkesy
+-- @description: Ungültige Steuerschlüssel in den Kontenrahmendefinitionen und daraus resultierende falsche Einträge in anderen Tabellen werden korrigiert.
+-- @depends: tax_primary_key_taxkeys_foreign_keys
+UPDATE chart SET taxkey_id = 0 WHERE taxkey_id NOT IN (SELECT DISTINCT taxkey_id FROM taxkeys);
+UPDATE taxkeys SET taxkey_id = 0, tax_id = 0 WHERE taxkey_id NOT IN (SELECT DISTINCT taxkey_id FROM taxkeys);
 
--- /dev/null
+-- @tag: language_output_formatting
+-- @description: Speichern des Ausgabeformates für Zahlen und Datumsangaben bei jeder Sprache.
+-- @depends:
+ALTER TABLE language ADD COLUMN output_numberformat text;
+ALTER TABLE language ADD COLUMN output_dateformat text;
+ALTER TABLE language ADD COLUMN output_longdates boolean;
 
--- /dev/null
+-- @tag: release_2_4_1
+-- @description: Leeres Script, das von allen bis zum Release 2.4.1 hinzugefügten Upgradescripten abhängt, um ein fest definiertes Schema für 2.4.1 zu definieren.
+-- @depends: chart_names rename_buchungsgruppen_accounts_16_19_percent language_output_formatting units_translations_and_singular_plural_distinction invalid_taxkesy customer_vendor_ustid_length
 
--- /dev/null
+-- @tag: rename_buchungsgruppen_accounts_16_19_percent
+-- @description: Benennt einige Buchungsgruppen und Konten von "... 16%" in "... 16%/19%" um. Wird nur beim SKR03 und SKR04 gemacht.
+-- @depends:
+UPDATE buchungsgruppen
+  SET description = 'Standard 16%/19%'
+  WHERE
+    ((SELECT coa FROM defaults) IN ('Germany-DATEV-SKR03EU', 'Germany-DATEV-SKR04EU')) AND
+    (description = 'Standard 16%');
+UPDATE chart SET description = replace(description, '16%', '16%/19%')
+  WHERE
+    ((SELECT coa FROM defaults) IN ('Germany-DATEV-SKR03EU', 'Germany-DATEV-SKR04EU')) AND
+    (link NOT ILIKE '%tax%') AND
+    (description ~ '16%') AND (description !~ '19%');
 
--- /dev/null
+-- @tag: tax_id_if_taxkey_is_0
+-- @description: Aktualisierung der Spalte tax.id, wenn tax.taxkey = 0 ist.
+-- @depends:
+UPDATE tax SET id = 0 WHERE taxkey = 0;
+UPDATE taxkeys SET tax_id = 0 WHERE taxkey_id = 0;
 
--- /dev/null
+-- @tag: tax_primary_key_taxkeys_foreign_keys
+-- @description: Legt in tax einen neuen Primärschlüssel und in taxkeys einen neuen Fremdschlüssel auf tax an.
+-- @depends: tax_id_if_taxkey_is_0
+UPDATE taxkeys SET tax_id = 0 WHERE taxkey_id = 0;
+ALTER TABLE tax ADD PRIMARY KEY (id);
+ALTER TABLE taxkeys ADD FOREIGN KEY (tax_id) REFERENCES tax (id);
 
--- /dev/null
+-- @tag: units_translations_and_singular_plural_distinction
+-- @description: Für jede Einheit kann für jede Sprache eine Übersetzung sowie eine Unterscheidung zwischen Singular und Plural gespeichert werden.
+-- @depends:
+CREATE TABLE units_language (
+       unit varchar (20) NOT NULL,
+       language_id integer NOT NULL,
+       localized varchar (20),
+       localized_plural varchar (20),
+
+       FOREIGN KEY (unit) REFERENCES units (name),
+       FOREIGN KEY (language_id) REFERENCES language (id)
+);
+CREATE INDEX units_name_idx ON units (name);
+CREATE INDEX units_language_unit_idx ON units_language (unit);
 
 
-<body bgcolor=ffffff>
+<body bgcolor="#ffffff">
 
-<h2 align=center>
+<h2 align="center">
 <%company%>
 <br><%address%>
 
 <br><%period%>
 </h2>
 
-<table border=0>
+<table border="0">
 <tr>
-  <th align=left width=400 colspan=2>AKTIVA<br><hr align=left width=250 size=5 noshade></th>
+  <th align="left" width="400" colspan="2">AKTIVA<br><hr align="left" width="250" size="5" noshade></th>
   <th><%this_period%></th>
   <th><%last_period%></th>
 </tr>
 <tr>
   <td> </td>
   <td><%asset_account%></td>
-  <td align=right><%asset_this_period%></td>
-  <td align=right><%asset_last_period%></td>
+  <td align="right"><%asset_this_period%></td>
+  <td align="right"><%asset_last_period%></td>
 </tr>
 <%end asset_account%>
 
 <tr>
-  <td colspan=2> </td>
-  <td><hr noshade size=1></td>
-  <td><hr noshade size=1></td>
+  <td colspan="2"> </td>
+  <td><hr noshade size="1"></td>
+  <td><hr noshade size="1"></td>
 </tr>
 
-<tr valign=top>
-  <th align=left colspan=2>TOTAL</th>
-  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
-  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+<tr valign="top">
+  <th align="left" colspan="2">TOTAL</th>
+  <td align="right"><%total_assets_this_period%><hr noshade size="2"></td>
+  <td align="right"><%total_assets_last_period%><hr noshade size="2"></td>
 </tr>
 
 <tr>
-  <th align=left colspan=4>PASSIVA<b><hr align=left width=250 size=5 noshade></th>
+  <th align="left" colspan="4">PASSIVA<b><hr align="left" width="250" size="5" noshade></th>
 </tr>
 
 <%foreach liability_account%>
 <tr>
   <td></td>
   <td><%liability_account%></td>
-  <td align=right><%liability_this_period%></td>
-  <td align=right><%liability_last_period%></td>
+  <td align="right"><%liability_this_period%></td>
+  <td align="right"><%liability_last_period%></td>
 </tr>
 <%end liability_account%>
 
 <tr>
-  <td colspan=2> </td>
-  <td><hr noshade size=1></td>
-  <td><hr noshade size=1></td>
+  <td colspan="2"> </td>
+  <td><hr noshade size="1"></td>
+  <td><hr noshade size="1"></td>
 </tr>
 
-<tr valign=top>
+<tr valign="top">
   <td></td>
-  <th align=left>TOTAL</th>
-  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
-  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+  <th align="left">TOTAL</th>
+  <td align="right"><%total_liabilities_this_period%><br><hr noshade size="2"</td>
+  <td align="right"><%total_liabilities_last_period%><br><hr noshade size="2"</td>
 </tr>
 
 <tr>
-  <th align=left colspan=4>EIGENTUM<br><hr align=left width=250 size=5 noshade></th>
+  <th align="left" colspan="4">EIGENTUM<br><hr align="left" width="250" size="5" noshade></th>
 </tr>
 
 <%foreach equity_account%>
 <tr>
   <td></td>
   <td><%equity_account%></td>
-  <td align=right><%equity_this_period%></td>
-  <td align=right><%equity_last_period%></td>
+  <td align="right"><%equity_this_period%></td>
+  <td align="right"><%equity_last_period%></td>
 </tr>
 <%end equity_account%>
 
 <tr>
-  <td colspan=2> </td>
-  <td><hr noshade size=1></td>
-  <td><hr noshade size=1></td>
+  <td colspan="2"> </td>
+  <td><hr noshade size="1"></td>
+  <td><hr noshade size="1"></td>
 </tr>
 
-<tr valign=top>
+<tr valign="top">
   <td></td>
-  <th align=left>TOTAL</th>
-  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
-  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+  <th align="left">TOTAL</th>
+  <td align="right"><%total_equity_this_period%><br><hr noshade size="2"</td>
+  <td align="right"><%total_equity_last_period%><br><hr noshade size="2"</td>
 </tr>
 
-<tr valign=top>
-  <th align=left colspan=2>TOTAL PASSIVA & EIGETNTUM</th>
-  <td align=right><%total_this_period%><br><hr noshade size=2></td>
-  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+<tr valign="top">
+  <th align="left" colspan="2">TOTAL PASSIVA & EIGENTUM</th>
+  <td align="right"><%total_this_period%><br><hr noshade size="2"></td>
+  <td align="right"><%total_last_period%><br><hr noshade size="2"></td>
 </tr>
 </table>
 
 
 </tr>
 
 <tr class="white">
-       <td class="left"><nobr>übrige Steuern</nobr></td>
+       <td class="left"><nobr>Übrige Steuern</nobr></td>
        <td><nobr><%jetzt19%></nobr></td>
        <td><nobr><%jetztgl19%></nobr></td>
        <td><nobr><%jetztgk19%></nobr></td>
 
 <tr>
        <td colspan=11 class=footer>Währung: Euro - FiBu: LX Office ERP
-(Version 2.1.1) - Formular: 16.04.2005</td>
+(Version <%version%>) - Formular: 11.01.2007</td>
 </tr>
 
 </table>
 
   <td><br><br></td>
 </tr>
 <tr>
-  <td align=left><font size="+1"><b>B. Betriebsaussgaben</font></b><br></td>
+  <td align=left><font size="+1"><b>B. Betriebsausgaben</font></b><br></td>
   <td></td>
 </tr>
 
 
-;; This file was produced using taxbird. 
+;; This file was produced using lx-office
+;; for using in taxbird. 
 ;; You probably don't want to touch this 
 ;; file. In case you do want it anyway, 
 ;; be warned: BE CAREFUL!!
 ;;
 '("Umsatzsteuervoranmeldung <%year%>" (
 ("vend-id" . "74931")
-("land-lieferant" . "<%nation%>")
+("land-lieferant" . "<%elsterland%>")
 ("name-lieferant" . "<%company%>")
 ("berufsbez" . "")
 ("strasse-lieferant" . "<%co_street%>")
-("plz-lieferant" . "<%co_zip%>")
+("plz-lieferant" . "<%co_zip%> ")
 ("ort-lieferant" . "<%co_city%>")
-("vorwahl" . "")
+("vorwahl" . "<%co_phone_prefix%>")
 ("anschluss" . "<%co_phone%>")
-("land" . "<%elsterland%>")
-("zeitraum" . "<%period%>")
-("stnr" . "<%steuernummer%>")
+("land" . "<%taxbird_land_nr%>")
+("zeitraum" . "<%taxbird_period%>")
+("stnr" . "<%taxbird_steuernummer%>")
 
 <%if 10%>("Kz10" . "<%10%>")<%end 10%>
 <%if 22%>("Kz22" . "<%22%>")<%end 22%>
 
--- /dev/null
+% German USTVA template for taxreports
+%
+% Contributed by Jens Koerner, Peter Schorer, Udo Spallek
+%
+%
+\documentclass[twoside]{scrartcl}
+\usepackage{a4,german}
+\usepackage[frame]{xy}
+\usepackage[latin1]{inputenc}
+\usepackage[german]{babel}
+\usepackage{graphicx}
+\usepackage{tabularx}
+\usepackage{times, german}
+\usepackage{german}
+\setlength{\voffset}{-0.8cm} %hier wird die Höhenverschiebung getätigt
+\setlength{\hoffset}{-1cm}  %und hier die Verschiebung seitwärts
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{0cm}
+\setlength{\evensidemargin}{0cm}
+\setlength{\textwidth}{20.9cm}
+\setlength{\textheight}{29.6cm}
+\setlength{\footskip}{-0cm}
+\setlength{\parindent}{0pt}
+
+\begin{document}
+
+\fontfamily{cmss}\fontshape{n}\large\selectfont
+\pagestyle{myheadings}
+\markboth{\protect\scalebox{1.045}[1.045]{\protect\includegraphics[viewport = 54 783 700 790]{ustva-2007-2.pdf}}}
+{\protect\scalebox{1.045}[1.045]{\protect\includegraphics[viewport = 70 700 700 790]{ustva-2007-1.pdf}}}
+\hspace{1mm}
+\begin{tabular}[b]{p{7mm}p{5cm}p{22.5mm}p{24mm}p{7mm}p{28mm}p{3mm}}
+\multicolumn{7}{c}{}\\[-2mm]
+ &  \multicolumn{6}{l}{<%steuernummer%>}\\
+\multicolumn{7}{c}{}\\[15mm]
+\multicolumn{2}{p{7.5cm}}{<%FA_Name%>} & & & & &\\[-4mm]
+\multicolumn{2}{p{7.5cm}}{}  & & & & &\\[3mm]
+\multicolumn{2}{p{7.5cm}}{<%FA_Strasse%>} & &<%0401%>&<%0407%>&&<%0441%>\\[1.2mm]
+\multicolumn{2}{p{7.5cm}}{} & &<%0402%>&<%0408%>&&<%0442%>\\[1.25mm]
+\multicolumn{2}{p{7.5cm}}{<%FA_PLZ%> <%FA_Ort%>} & &<%0403%>&<%0409%>&&<%0443%>\\[3mm]
+\multicolumn{2}{p{7.5cm}}{} & &<%0404%>&<%0410%>&&<%0444%>\\[1.25mm]
+\multicolumn{2}{p{7.5cm}}{} & &<%0405%>&<%0411%>&&\\[1.25mm]
+\multicolumn{2}{p{7.5cm}}{\small{<%company%>}} & &<%0406%>&<%0412%>&&\\[-1mm]
+\multicolumn{2}{p{7.5cm}}{\small{<%co_street%>}}& & & & &\\[-1mm]
+\multicolumn{2}{p{7.5cm}}{\small{<%co_city%>}}& & & &<%FA_10%> &\\[1mm]
+\multicolumn{2}{p{7.5cm}}{
+<%if tel%>
+\small{Tel: <%tel%>}~--~
+<%end tel%>
+<%if fax%>
+\small{Fax: <%fax%>}
+<%end fax%>
+}& & & & &\\[-1mm]
+\multicolumn{2}{p{7.5cm}}{\small{<%email%>}}& & & & &\\[-1mm]
+\end{tabular}\\[29.5mm]
+\begin{tabular}[b]{p{99mm}p{26.5mm}p{4.55mm}p{4mm}p{35mm}}
+&&&&\\[20.5mm]
+\multicolumn{2}{r}{<%48%>} & & \multicolumn{2}{r}{}\\[7.5mm]
+\multicolumn{2}{r}{<%51%>} & & \multicolumn{2}{r}{<%511%>}\\[1.5mm]
+\multicolumn{2}{r}{<%86%>} & & \multicolumn{2}{r}{<%861%>}\\[42mm]
+\multicolumn{2}{r}{<%97%>} & & \multicolumn{2}{r}{<%971%>}\\[1.5mm]
+\multicolumn{2}{r}{<%93%>} & & \multicolumn{2}{r}{<%931%>}\\[8.5mm]
+\multicolumn{2}{r}{<%94%>} & & \multicolumn{2}{r}{<%96%>}\\[28mm]
+\multicolumn{2}{r}{} & & \multicolumn{2}{r}{<%Z43%>}\\
+\end{tabular}
+
+\newpage
+
+\vspace*{-9.5mm}\hspace{27mm}<%steuernummer%>\\[-2.7mm]
+\begin{tabular}[b]{p{99mm}p{25.2mm}p{2.55mm}p{10mm}p{32mm}}
+&&&&\\
+\multicolumn{2}{r}{} & & \multicolumn{2}{r}{<%Z45%>}\\[48mm]
+\multicolumn{2}{r}{} & & \multicolumn{2}{r}{<%Z53%>}\\[8.9mm]
+\multicolumn{2}{r}{} & & \multicolumn{2}{r}{<%66%>}\\[42mm]
+\multicolumn{2}{r}{} & & \multicolumn{2}{r}{<%Z62%>}\\[28mm]
+\multicolumn{2}{r}{} & & \multicolumn{2}{r}{\textbf{<%83%>}}\\[26mm]
+\end{tabular}\\[35mm]
+<%if FA_steuerberater%>
+\vspace{11mm}
+\begin{list}{}{
+\setlength{\leftmargin}{2mm}
+\setlength{\itemsep}{0mm}
+\setlength{\parsep}{0mm}
+%\setlength{\topsep}{0mm}
+%\setlength{\parskip}{0mm}
+%\setlength{\partopsep}{0mm}
+}
+\begin{small}
+\item <%FA_steuerberater_name%>
+\item <%FA_steuerberater_street%>
+\item <%FA_steuerberater_city%>
+\item Tel:~<%FA_steuerberater_tel%>
+\end{small}\\[15mm]
+\item  <%Datum_heute%>,
+\end{list}
+<%end FA_steuerberater%>
+<%if not FA_steuerberater%>
+\begin{list}{}{
+\setlength{\leftmargin}{2mm}
+\setlength{\itemsep}{0mm}
+\setlength{\parsep}{0mm}
+%\setlength{\topsep}{0mm}
+%\setlength{\parskip}{0mm}
+%\setlength{\partopsep}{0mm}
+}
+\begin{small}
+\item ~
+\item ~
+\item ~
+\item ~
+\end{small}\\[26mm]
+\item  <%Datum_heute%>,
+\end{list}
+<%end FA_steuerberater%>
+\end{document}
+
+
+
+
+
+
+
+
+
+
 
 <%FA_steuerberater_street%><br />
 <%FA_steuerberater_city%><br />
 Tel: <%FA_steuerberater_tel%></p>
-<%end FA_steuerberater%>>
+<%end FA_steuerberater%>
 </body>
 </html>
 
    <th align="right">Faktor</th>
    <td><input name="new_factor"></td>
   </tr>
+
+  <TMPL_LOOP LANGUAGES>
+   <tr>
+    <th align="right"><TMPL_VAR description></th>
+    <td><input name="new_localized_<TMPL_VAR id>" size="20" maxlength="20"></td>
+    <th align="right">Plural</th>
+    <td><input name="new_localized_plural_<TMPL_VAR id>" size="20" maxlength="20"></td>
+   </tr>
+  </TMPL_LOOP>
  </table>
 
  <input type="submit" class="submit" name="action" value="Erfassen">
   gelöscht.
  </p>
 
+ <p>
+  Bei den Übersetzungen können Sie unterschiedliche
+  Varianten für singular und plural angeben (z.B. "day"
+  und "days").
+ </p>
+
  <table>
   <tr>
    <th class="listheading"> </th>
    <th class="listheading">Einheit</th>
    <th class="listheading">Basiseinheit</th>
    <th class="listheading">Faktor</th>
+   <TMPL_LOOP LANGUAGES>
+    <th class="listheading"><TMPL_VAR description></th>
+   </TMPL_LOOP>
   </tr>
 
   <TMPL_LOOP NAME=UNITS>
      <td align="center"><input type="checkbox" name="delete_<TMPL_VAR NAME=__counter__>"></td>
      <td>
       <input type="hidden" name="old_name_<TMPL_VAR NAME=__counter__>" value="<TMPL_VAR NAME=name>">
-      <input name="name_<TMPL_VAR NAME=__counter__>" size="20" maxlength="20" value="<TMPL_VAR NAME=name>">
+      <input name="name_<TMPL_VAR NAME=__counter__>" size="10" maxlength="20" value="<TMPL_VAR NAME=name>">
      </td>
      <td>
       <select name="base_unit_<TMPL_VAR NAME=__counter__>">
        <TMPL_LOOP NAME=BASE_UNIT_DDBOX><option <TMPL_VAR NAME=selected>><TMPL_VAR NAME=name></option></TMPL_LOOP>
       </select>
      </td>
-     <td><input name="factor_<TMPL_VAR NAME=__counter__>" value="<TMPL_VAR NAME=factor>"></td>
-
+     <td><input name="factor_<TMPL_VAR NAME=__counter__>" size="8" value="<TMPL_VAR NAME=factor>"></td>
     </TMPL_IF>
+
+    <TMPL_LOOP UNITLANGUAGES>
+     <td>
+      S:
+      <input name="localized_<TMPL_VAR idx>_<TMPL_VAR language_id>" value="<TMPL_VAR localized>" size="6" maxlength="20">
+      P:
+      <input name="localized_plural_<TMPL_VAR idx>_<TMPL_VAR language_id>" value="<TMPL_VAR localized_plural>" size="6" maxlength="20">
+     </td>
+    </TMPL_LOOP>
    </tr>
 
    <TMPL_IF NAME=__last__><input type="hidden" name="rowcount" value="<TMPL_VAR NAME=__counter__>"></TMPL_IF>
 
    <th align="right"><translate>Factor</translate></th>
    <td><input name="new_factor"></td>
   </tr>
+
+  <TMPL_LOOP LANGUAGES>
+   <tr>
+    <th align="right"><TMPL_VAR description></th>
+    <td><input name="new_localized_<TMPL_VAR id>" size="20" maxlength="20"></td>
+    <th align="right"><translate>Plural</translate></th>
+    <td><input name="new_localized_plural_<TMPL_VAR id>" size="20" maxlength="20"></td>
+   </tr>
+  </TMPL_LOOP>
  </table>
 
  <input type="submit" class="submit" name="action" value="<translate>Add</translate>">
   gelöscht.
  </p>
 
+ <p>
+  Bei den Übersetzungen können Sie unterschiedliche
+  Varianten für singular und plural angeben (z.B. "day"
+  und "days").
+ </p>
+
  <table>
   <tr>
    <th class="listheading"> </th>
    <th class="listheading"><translate>Unit</translate></th>
    <th class="listheading"><translate>Base unit</translate></th>
    <th class="listheading"><translate>Factor</translate></th>
+   <TMPL_LOOP LANGUAGES>
+    <th class="listheading"><TMPL_VAR description></th>
+   </TMPL_LOOP>
   </tr>
 
   <TMPL_LOOP NAME=UNITS>
      <td align="center"><input type="checkbox" name="delete_<TMPL_VAR NAME=__counter__>"></td>
      <td>
       <input type="hidden" name="old_name_<TMPL_VAR NAME=__counter__>" value="<TMPL_VAR NAME=name>">
-      <input name="name_<TMPL_VAR NAME=__counter__>" size="20" maxlength="20" value="<TMPL_VAR NAME=name>">
+      <input name="name_<TMPL_VAR NAME=__counter__>" size="10" maxlength="20" value="<TMPL_VAR NAME=name>">
      </td>
      <td>
       <select name="base_unit_<TMPL_VAR NAME=__counter__>">
        <TMPL_LOOP NAME=BASE_UNIT_DDBOX><option <TMPL_VAR NAME=selected>><TMPL_VAR NAME=name></option></TMPL_LOOP>
       </select>
      </td>
-     <td><input name="factor_<TMPL_VAR NAME=__counter__>" value="<TMPL_VAR NAME=factor>"></td>
-
+     <td><input name="factor_<TMPL_VAR NAME=__counter__>" size="8" value="<TMPL_VAR NAME=factor>"></td>
     </TMPL_IF>
+
+    <TMPL_LOOP UNITLANGUAGES>
+     <td>
+      <translate>singular first char</translate>:
+      <input name="localized_<TMPL_VAR idx>_<TMPL_VAR language_id>" value="<TMPL_VAR localized>" size="6" maxlength="20">
+      <translate>plural first char</translate>:
+      <input name="localized_plural_<TMPL_VAR idx>_<TMPL_VAR language_id>" value="<TMPL_VAR localized_plural>" size="6" maxlength="20">
+     </td>
+    </TMPL_LOOP>
    </tr>
 
    <TMPL_IF NAME=__last__><input type="hidden" name="rowcount" value="<TMPL_VAR NAME=__counter__>"></TMPL_IF>
 
     <tr>
      <td>Inventar:</td>
      <td>
-      <input type="hidden" name="inventory_accno_id_<TMPL_VAR __counter__>" value="<TMPL_VAR inventory_accno_id ESCAPE=HTML>">
-      <TMPL_VAR inventory_accno ESCAPE=HTML>--<TMPL_VAR inventory_description ESCAPE=HTML>
+      <select name="inventory_accno_id_<TMPL_VAR __counter__>">
+       <TMPL_LOOP ACC_INVENTORY><option value="<TMPL_VAR id>" <TMPL_VAR selected>><TMPL_VAR accno ESCAPE=HTML>--<TMPL_VAR description ESCAPE=HTML></option></TMPL_LOOP>
+      </select>
      </td>
     </tr>
    </TMPL_IF>
 
     <tr>
      <td><translate>Inventory</translate>:</td>
      <td>
-      <input type="hidden" name="inventory_accno_id_<TMPL_VAR __counter__>" value="<TMPL_VAR inventory_accno_id ESCAPE=HTML>">
-      <TMPL_VAR inventory_accno ESCAPE=HTML>--<TMPL_VAR inventory_description ESCAPE=HTML>
+      <select name="inventory_accno_id_<TMPL_VAR __counter__>">
+       <TMPL_LOOP ACC_INVENTORY><option value="<TMPL_VAR id>" <TMPL_VAR selected>><TMPL_VAR accno ESCAPE=HTML>--<TMPL_VAR description ESCAPE=HTML></option></TMPL_LOOP>
+      </select>
      </td>
     </tr>
    </TMPL_IF>
 
 <p>...fertig</p>
 
-<form action="menu.pl">
+<form action="<TMPL_VAR menufile>">
 
  <input type="hidden" name="login" value="<TMPL_VAR login ESCAPE=HTML>">
  <input type="hidden" name="password" value="<TMPL_VAR password ESCAPE=HTML>">
 
 <p><translate>...done</translate></p>
 
-<form action="menu.pl">
+<form action="<TMPL_VAR menufile>">
 
  <input type="hidden" name="login" value="<TMPL_VAR login ESCAPE=HTML>">
  <input type="hidden" name="password" value="<TMPL_VAR password ESCAPE=HTML>">
 
--- /dev/null
+<ul>
+ <li>Führe <TMPL_VAR file ESCAPE=HTML> aus: <TMPL_VAR description></li>
+</ul>
+
 
--- /dev/null
+<ul>
+ <li><translate>Applying <TMPL_VAR file ESCAPE=HTML>:</translate> <TMPL_VAR description></li>
+</ul>
+