Implementation des Features "Benutzerdefinierte Variablen für Kunden- und Lieferanten...
authorMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 10 Jan 2008 17:14:51 +0000 (17:14 +0000)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 10 Jan 2008 17:14:51 +0000 (17:14 +0000)
40 files changed:
SL/CT.pm
SL/CVar.pm [new file with mode: 0644]
SL/IR.pm
SL/IS.pm
amcvar.pl [new symlink]
bin/mozilla/amcvar.pl [new file with mode: 0644]
bin/mozilla/ct.pl
bin/mozilla/io.pl
doc/dokumentenvorlagen-und-variablen.html
locale/de/all
locale/de/amcvar [new file with mode: 0644]
locale/de/ap
locale/de/ar
locale/de/cp
locale/de/ct
locale/de/dn
locale/de/gl
locale/de/ic
locale/de/io
locale/de/ir
locale/de/is
locale/de/licenses
locale/de/menu
locale/de/menunew
menu.ini
sql/Pg-upgrade2/custom_variables.sql [new file with mode: 0644]
templates/webpages/amcvar/display_cvar_config_form_de.html [new file with mode: 0644]
templates/webpages/amcvar/display_cvar_config_form_master.html [new file with mode: 0644]
templates/webpages/amcvar/list_cvar_configs_de.html [new file with mode: 0644]
templates/webpages/amcvar/list_cvar_configs_master.html [new file with mode: 0644]
templates/webpages/amcvar/render_inputs_de.html [new file with mode: 0644]
templates/webpages/amcvar/render_inputs_master.html [new file with mode: 0644]
templates/webpages/amcvar/search_filter_de.html [new file with mode: 0644]
templates/webpages/amcvar/search_filter_master.html [new file with mode: 0644]
templates/webpages/amcvar/search_include_de.html [new file with mode: 0644]
templates/webpages/amcvar/search_include_master.html [new file with mode: 0644]
templates/webpages/ct/form_header_de.html
templates/webpages/ct/form_header_master.html
templates/webpages/ct/search_de.html
templates/webpages/ct/search_master.html

index e5ee4af..e0e4084 100644 (file)
--- a/SL/CT.pm
+++ b/SL/CT.pm
 #======================================================================
 
 package CT;
+
 use Data::Dumper;
+
+use SL::CVar;
 use SL::DBUtils;
 
 sub get_tuple {
@@ -381,6 +384,11 @@ sub save_customer {
   # add shipto
   $form->add_shipto( $dbh, $form->{id}, "CT" );
 
+  CVar->save_custom_variables('dbh'       => $dbh,
+                              'module'    => 'CT',
+                              'trans_id'  => $form->{id},
+                              'variables' => $form);
+
   $rc = $dbh->commit();
   $dbh->disconnect();
 
@@ -578,6 +586,11 @@ sub save_vendor {
   # add shipto
   $form->add_shipto( $dbh, $form->{id}, "CT" );
 
+  CVar->save_custom_variables('dbh'       => $dbh,
+                              'module'    => 'CT',
+                              'trans_id'  => $form->{id},
+                              'variables' => $form);
+
   $rc = $dbh->commit();
   $dbh->disconnect();
 
@@ -666,6 +679,15 @@ sub search {
     push(@values, conv_i($form->{business_id}));
   }
 
+  my ($cvar_where, @cvar_values) = CVar->build_filter_query('module'         => 'CT',
+                                                            'trans_id_field' => 'ct.id',
+                                                            'filter'         => $form);
+
+  if ($cvar_where) {
+    $where .= qq| AND ($cvar_where)|;
+    push @values, @cvar_values;
+  }
+
   my $query =
     qq|SELECT ct.*, b.description AS business | .
     qq|FROM $cv ct | .
diff --git a/SL/CVar.pm b/SL/CVar.pm
new file mode 100644 (file)
index 0000000..8037958
--- /dev/null
@@ -0,0 +1,543 @@
+package CVar;
+
+use List::Util qw(first);
+
+use SL::DBUtils;
+
+sub get_configs {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my ($where, @values);
+  if ($params{module}) {
+    $where = 'WHERE module = ?';
+    push @values, $params{module};
+  }
+
+  my $query    = qq|SELECT * FROM custom_variable_configs $where ORDER BY sortkey|;
+
+  my $configs  = selectall_hashref_query($form, $dbh, $query, @values);
+
+  foreach my $config (@{ $configs }) {
+    if ($config->{type} eq 'select') {
+      $config->{OPTIONS} = [ map { { 'value' => $_ } } split(m/\#\#/, $config->{options}) ];
+
+    } elsif ($config->{type} eq 'number') {
+      $config->{precision} = $1 if ($config->{options} =~ m/precision=(\d+)/i);
+
+    }
+  }
+
+  $main::lxdebug->leave_sub();
+
+  return $configs;
+}
+
+sub get_config {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(id));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my $query    = qq|SELECT * FROM custom_variable_configs WHERE id = ?|;
+
+  my $config   = selectfirst_hashref_query($form, $dbh, $query, conv_i($params{id})) || { };
+
+  $main::lxdebug->leave_sub();
+
+  return $config;
+}
+
+sub save_config {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(module config));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my $q_id     = qq|SELECT nextval('custom_variable_configs_id')|;
+  my $h_id     = prepare_query($form, $dbh, $q_id);
+
+  my $q_new    =
+    qq|INSERT INTO custom_variable_configs (name, description, type, default_value, options, searchable, includeable, included_by_default, module, id, sortkey)
+       VALUES                              (?,    ?,           ?,    ?,             ?,       ?,          ?,           ?,                   ?,      ?,
+         (SELECT COALESCE(MAX(sortkey) + 1, 1) FROM custom_variable_configs))|;
+  my $h_new    = prepare_query($form, $dbh, $q_new);
+
+  my $q_update =
+    qq|UPDATE custom_variable_configs SET
+         name        = ?, description         = ?,
+         type        = ?, default_value       = ?,
+         options     = ?, searchable          = ?,
+         includeable = ?, included_by_default = ?,
+         module      = ?
+       WHERE id  = ?|;
+  my $h_update = prepare_query($form, $dbh, $q_update);
+
+  my @configs;
+  if ('ARRAY' eq ref $params{config}) {
+    @configs = @{ $params{config} };
+  } else {
+    @configs = ($params{config});
+  }
+
+  foreach my $config (@configs) {
+    my ($h_actual, $q_actual);
+
+    if (!$config->{id}) {
+      do_statement($form, $h_id, $q_id);
+      ($config->{id}) = $h_id->fetchrow_array();
+
+      $h_actual       = $h_new;
+      $q_actual       = $q_new;
+
+    } else {
+      $h_actual       = $h_update;
+      $q_actual       = $q_update;
+    }
+
+    do_statement($form, $h_actual, $q_actual, @{$config}{qw(name description type default_value options)},
+                 $config->{searchable} ? 't' : 'f', $config->{includeable} ? 't' : 'f', $config->{included_by_default} ? 't' : 'f',
+                 $params{module}, conv_i($config->{id}));
+  }
+
+  $h_id->finish();
+  $h_new->finish();
+  $h_update->finish();
+
+  $dbh->commit();
+
+  $main::lxdebug->leave_sub();
+}
+
+sub delete_config {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(id));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  do_query($form, $dbh, qq|DELETE FROM custom_variables        WHERE config_id = ?|, conv_i($params{id}));
+  do_query($form, $dbh, qq|DELETE FROM custom_variable_configs WHERE id        = ?|, conv_i($params{id}));
+
+  $dbh->commit();
+
+  $main::lxdebug->leave_sub();
+}
+
+sub get_custom_variables {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(module));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my $trans_id = $params{trans_id} ? 'OR (v.trans_id = ?) ' : '';
+
+  my $q_cfg    =
+    qq|SELECT id, name, description, type, default_value, options,
+         date_trunc('seconds', localtimestamp) AS current_timestamp, current_date AS current_date
+       FROM custom_variable_configs
+       WHERE module = ?
+       ORDER BY sortkey|;
+
+  my $q_var    =
+    qq|SELECT text_value, timestamp_value, timestamp_value::date AS date_value, number_value, bool_value
+       FROM custom_variables
+       WHERE (config_id = ?) AND (trans_id = ?)|;
+  my $h_var    = prepare_query($form, $dbh, $q_var);
+
+  my $custom_variables = selectall_hashref_query($form, $dbh, $q_cfg, $params{module});
+
+  foreach my $cvar (@{ $custom_variables }) {
+    if ($cvar->{type} eq 'textfield') {
+      $cvar->{width}  = 30;
+      $cvar->{height} =  5;
+
+      $cvar->{width}  = $1 if ($cvar->{options} =~ m/width=(\d+)/i);
+      $cvar->{height} = $1 if ($cvar->{options} =~ m/height=(\d+)/i);
+
+    } elsif ($cvar->{type} eq 'text') {
+      $cvar->{maxlength} = $1 if ($cvar->{options} =~ m/maxlength=(\d+)/i);
+
+    } elsif ($cvar->{type} eq 'number') {
+      $cvar->{precision} = $1 if ($cvar->{options} =~ m/precision=(\d+)/i);
+
+    } elsif ($cvar->{type} eq 'select') {
+      $cvar->{OPTIONS} = [ map { { 'value' => $_ } } split(m/\#\#/, $cvar->{options}) ];
+    }
+
+    my $act_var;
+    if ($params{trans_id}) {
+      do_statement($form, $h_var, $q_var, conv_i($cvar->{id}), conv_i($params{trans_id}));
+      $act_var = $h_var->fetchrow_hashref();
+    }
+
+    if ($act_var) {
+      $cvar->{value} = $cvar->{type} eq 'date'      ? $act_var->{date_value}
+                     : $cvar->{type} eq 'timestamp' ? $act_var->{timestamp_value}
+                     : $cvar->{type} eq 'number'    ? $act_var->{number_value}
+                     : $cvar->{type} eq 'bool'      ? $act_var->{bool_value}
+                     :                                $act_var->{text_value};
+
+    } else {
+      if ($cvar->{type} eq 'date') {
+        if ($cvar->{default_value} eq 'NOW') {
+          $cvar->{value} = $cvar->{current_date};
+        } else {
+          $cvar->{value} = $cvar->{default_value};
+        }
+
+      } elsif ($cvar->{type} eq 'timestamp') {
+        if ($cvar->{default_value} eq 'NOW') {
+          $cvar->{value} = $cvar->{current_timestamp};
+        } else {
+          $cvar->{value} = $cvar->{default_value};
+        }
+
+      } elsif ($cvar->{type} eq 'bool') {
+        $cvar->{value} = $cvar->{default_value} * 1;
+
+      } elsif ($cvar->{type} eq 'number') {
+        $cvar->{value} = $cvar->{default_value} * 1 if ($cvar->{default_value} ne '');
+
+      } else {
+        $cvar->{value} = $cvar->{default_value};
+      }
+    }
+
+    if ($cvar->{type} eq 'number') {
+      $cvar->{value} = $form->format_amount($myconfig, $cvar->{value} * 1, $cvar->{precision});
+    }
+  }
+
+  $h_var->finish();
+
+  $main::lxdebug->leave_sub();
+
+  return $custom_variables;
+}
+
+sub save_custom_variables {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(module trans_id variables));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my @configs  = grep { $_->{module} eq $params{module} } @{ CVar->get_configs() };
+
+  my $query    =
+    qq|DELETE FROM custom_variables
+       WHERE (trans_id  = ?)
+         AND (config_id IN (SELECT DISTINCT id
+                            FROM custom_variable_configs
+                            WHERE module = ?))|;
+  do_query($form, $dbh, $query, conv_i($params{trans_id}), $params{module});
+
+  $query  =
+    qq|INSERT INTO custom_variables (config_id, trans_id, bool_value, timestamp_value, text_value, number_value)
+       VALUES                       (?,         ?,        ?,          ?,               ?,          ?)|;
+  my $sth = prepare_query($form, $dbh, $query);
+
+  foreach my $config (@configs) {
+    my @values = (conv_i($config->{id}), conv_i($params{trans_id}));
+
+    my $value  = $params{variables}->{"cvar_$config->{name}"};
+
+    if (($config->{type} eq 'text') || ($config->{type} eq 'textfield') || ($config->{type} eq 'select')) {
+      push @values, undef, undef, $value, undef;
+
+    } elsif (($config->{type} eq 'date') || ($config->{type} eq 'timestamp')) {
+      push @values, undef, conv_date($value), undef, undef;
+
+    } elsif ($config->{type} eq 'number') {
+      push @values, undef, undef, undef, conv_i($form->parse_amount($myconfig, $value));
+
+    } elsif ($config->{type} eq 'bool') {
+      push @values, $value ? 't' : 'f', undef, undef, undef;
+    }
+
+    do_statement($form, $sth, $query, @values);
+  }
+
+  $sth->finish();
+
+  $dbh->commit();
+
+  $main::lxdebug->leave_sub();
+}
+
+sub render_inputs {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(variables));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  foreach my $var (@{ $params{variables} }) {
+    $var->{HTML_CODE} = $form->parse_html_template('amcvar/render_inputs', { 'var' => $var });
+  }
+
+  $main::lxdebug->leave_sub();
+}
+
+sub render_search_options {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(variables));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  $params{include_prefix}   = 'l_' unless defined($params{include_prefix});
+  $params{include_value}  ||= '1';
+
+  my $filter  = $form->parse_html_template('amcvar/search_filter',  \%params);
+  my $include = $form->parse_html_template('amcvar/search_include', \%params);
+
+  $main::lxdebug->leave_sub();
+
+  return ($filter, $include);
+}
+
+sub build_filter_query {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(module trans_id_field filter));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my $configs  = $self->get_configs(%params);
+
+  my (@where, @values);
+
+  foreach my $config (@{ $configs }) {
+    next unless ($config->{searchable});
+
+    my $name = "cvar_$config->{name}";
+
+    my (@sub_values, @sub_where, $not);
+
+    if (($config->{type} eq 'text') || ($config->{type} eq 'textfield')) {
+      next unless ($params{filter}->{$name});
+
+      push @sub_where,  qq|cvar.text_value ILIKE ?|;
+      push @sub_values, '%' . $params{filter}->{$name} . '%'
+
+    } elsif ($config->{type} eq 'select') {
+      next unless ($params{filter}->{$name});
+
+      push @sub_where,  qq|cvar.text_value = ?|;
+      push @sub_values, $params{filter}->{$name};
+
+    } elsif (($config->{type} eq 'date') || ($config->{type} eq 'timestamp')) {
+      my $name_from = "${name}_from";
+      my $name_to   = "${name}_to";
+
+      if ($params{filter}->{$name_from}) {
+        push @sub_where,  qq|cvar.timestamp_value >= ?|;
+        push @sub_values, conv_date($params{filter}->{$name_from});
+      }
+
+      if ($params{filter}->{$name_to}) {
+        push @sub_where,  qq|cvar.timestamp_value <= ?|;
+        push @sub_values, conv_date($params{filter}->{$name_to});
+      }
+
+    } elsif ($config->{type} eq 'number') {
+      next if ($params{filter}->{$name} eq '');
+
+      my $f_op = $params{filter}->{"${name}_qtyop"};
+
+      if ($f_op eq '==') {
+        $op  = '=';
+
+      } elsif ($f_op eq '=/=') {
+        $not = 'NOT';
+        $op  = '<>';
+
+      } elsif ($f_op eq '<') {
+        $not = 'NOT';
+        $op  = '>=';
+
+      } elsif ($f_op eq '<=') {
+        $not = 'NOT';
+        $op  = '>';
+
+      } elsif (($f_op eq '>') || ($f_op eq '>=')) {
+        $op  = $f_op;
+
+      } else {
+        $op  = '=';
+      }
+
+      push @sub_where,  qq|cvar.number_value $op ?|;
+      push @sub_values, $form->parse_amount($myconfig, $params{filter}->{$name});
+
+    } elsif ($config->{type} eq 'bool') {
+      next unless ($params{filter}->{$name});
+
+      $not = 'NOT' if ($params{filter}->{$name} eq 'no');
+      push @sub_where,  qq|COALESCE(cvar.bool_value, false) = TRUE|;
+    }
+
+    if (@sub_where) {
+      push @where,
+        qq|$not EXISTS(
+             SELECT cvar.id
+             FROM custom_variables cvar
+             LEFT JOIN custom_variable_configs cvarcfg ON (cvar.config_id = cvarcfg.id)
+             WHERE (cvarcfg.module = ?)
+               AND (cvarcfg.id     = ?)
+               AND (cvar.trans_id  = $params{trans_id_field})
+               AND | . join(' AND ', map { "($_)" } @sub_where) . qq|)|;
+      push @values, $params{module}, conv_i($config->{id}), @sub_values;
+    }
+  }
+
+  my $query = join ' AND ', @where;
+
+  $main::lxdebug->leave_sub();
+
+  return ($query, @values);
+}
+
+sub add_custom_variables_to_report {
+  $main::lxdebug->enter_sub();
+
+  my $self      = shift;
+  my %params    = @_;
+
+  Common::check_params(\%params, qw(module trans_id_field column_defs data configs));
+
+  my $myconfig  = \%main::myconfig;
+  my $form      = $main::form;
+  my $locale    = $main::locale;
+
+  my $dbh       = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my $configs   = [ grep { $_->{includeable} && $params{column_defs}->{"cvar_$_->{name}"}->{visible} } @{ $params{configs} } ];
+
+  if (!scalar(@{ $params{data} }) || ! scalar(@{ $configs })) {
+    $main::lxdebug->leave_sub();
+    return;
+  }
+
+  my %cfg_map   = map { $_->{id} => $_ } @{ $configs };
+  my @cfg_ids   = keys %cfg_map;
+
+  my $query     =
+    qq|SELECT text_value, timestamp_value, timestamp_value::date AS date_value, number_value, bool_value, config_id
+       FROM custom_variables
+       WHERE (config_id IN (| . join(', ', ('?') x scalar(@cfg_ids)) . qq|)) AND (trans_id = ?)|;
+  my $sth       = prepare_query($form, $dbh, $query);
+
+  foreach my $row (@{ $params{data} }) {
+    do_statement($form, $sth, $query, @cfg_ids, conv_i($row->{$params{trans_id_field}}));
+
+    while (my $ref = $sth->fetchrow_hashref()) {
+      my $cfg = $cfg_map{$ref->{config_id}};
+
+      $row->{"cvar_$cfg->{name}"} =
+          $cfg->{type} eq 'date'      ? $ref->{date_value}
+        : $cfg->{type} eq 'timestamp' ? $ref->{timestamp_value}
+        : $cfg->{type} eq 'number'    ? $form->format_amount($myconfig, $ref->{number_value} * 1, $config->{precision})
+        : $cfg->{type} eq 'bool'      ? ($ref->{bool_value} ? $locale->text('Yes') : $locale->text('No'))
+        :                               $ref->{text_value};
+    }
+  }
+
+  $sth->finish();
+
+  $main::lxdebug->leave_sub();
+}
+
+sub get_field_format_list {
+  $main::lxdebug->enter_sub();
+
+  my $self          = shift;
+  my %params        = @_;
+
+  Common::check_params(\%params, qw(module));
+
+  my $myconfig      = \%main::myconfig;
+  my $form          = $main::form;
+
+  my $dbh           = $params{dbh} || $form->get_standard_dbh($myconfig);
+
+  my $configs       = $self->get_configs(%params);
+
+  my $date_fields   = [];
+  my $number_fields = {};
+
+  foreach my $config (@{ $configs }) {
+    my $name = "$params{prefix}cvar_$config->{name}";
+    $main::lxdebug->message(0, "name  $name");
+    if ($config->{type} eq 'date') {
+      push @{ $date_fields }, $name;
+
+    } elsif ($config->{type} eq 'number') {
+      $number_fields->{$config->{precision}} ||= [];
+      push @{ $number_fields->{$config->{precision}} }, $name;
+    }
+  }
+
+  $main::lxdebug->leave_sub();
+
+  return ($date_fields, $number_fields);
+}
+
+
+1;
index 6950739..8fa92e6 100644 (file)
--- a/SL/IR.pm
+++ b/SL/IR.pm
@@ -1108,6 +1108,11 @@ sub vendor_details {
 
   map { $form->{$_} = $ref->{$_} } keys %$ref;
 
+  my $custom_variables = CVar->get_custom_variables('dbh'      => $dbh,
+                                                    'module'   => 'CT',
+                                                    'trans_id' => $form->{vendor_id});
+  map { $form->{"vc_cvar_$_->{name}"} = $_->{value} } @{ $custom_variables };
+
   $dbh->disconnect();
 
   $main::lxdebug->leave_sub();
index 8ecddff..367c861 100644 (file)
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -37,6 +37,7 @@ package IS;
 use List::Util qw(max);
 
 use SL::AM;
+use SL::CVar;
 use SL::Common;
 use SL::DBUtils;
 use SL::MoreCommon;
@@ -463,6 +464,12 @@ sub customer_details {
 
     map { $form->{"dv_$_"} = $ref->{$_} } keys %$ref;
   }
+
+  my $custom_variables = CVar->get_custom_variables('dbh'      => $dbh,
+                                                    'module'   => 'CT',
+                                                    'trans_id' => $form->{customer_id});
+  map { $form->{"vc_cvar_$_->{name}"} = $_->{value} } @{ $custom_variables };
+
   $dbh->disconnect;
 
   $main::lxdebug->leave_sub();
diff --git a/amcvar.pl b/amcvar.pl
new file mode 120000 (symlink)
index 0000000..385000d
--- /dev/null
+++ b/amcvar.pl
@@ -0,0 +1 @@
+am.pl
\ No newline at end of file
diff --git a/bin/mozilla/amcvar.pl b/bin/mozilla/amcvar.pl
new file mode 100644 (file)
index 0000000..57457ac
--- /dev/null
@@ -0,0 +1,193 @@
+#=====================================================================
+# 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
+#
+#
+# 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.
+#======================================================================
+#
+# administration
+#
+#======================================================================
+
+use SL::AM;
+use SL::CVar;
+use SL::Form;
+
+use Data::Dumper;
+
+1;
+
+require "bin/mozilla/common.pl";
+
+# end of main
+
+our %translations = ('text'      => $locale->text('Free-form text'),
+                     'textfield' => $locale->text('Text field'),
+                     'number'    => $locale->text('Number'),
+                     'date'      => $locale->text('Date'),
+                     'timestamp' => $locale->text('Timestamp'),
+                     'bool'      => $locale->text('Yes/No (Checkbox)'),
+                     'select'    => $locale->text('Selection'),
+                     );
+
+our @types = qw(text textfield number date bool select); # timestamp
+
+sub add {
+  add_cvar_config();
+}
+
+sub edit {
+  edit_cvar_config();
+}
+
+sub list_cvar_configs {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  $form->{module} ||= $form->{cvar_module};
+
+  my @configs = grep { $_->{module} eq $form->{module} } @{ CVar->get_configs() };
+
+  my $previous_config;
+
+  foreach (@configs) {
+    $_->{type_tr} = $translations{$_->{type}};
+
+    if ($previous_config) {
+      $previous_config->{next_id} = $_->{id};
+      $_->{previous_id}           = $previous_config->{id};
+    }
+
+    $previous_config = $_;
+  }
+
+  $form->{title} = $locale->text('List of custom variables');
+  $form->header();
+  print $form->parse_html_template('amcvar/list_cvar_configs', { 'CONFIGS' => \@configs });
+
+  $lxdebug->leave_sub();
+}
+
+sub add_cvar_config {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  $form->{module} ||= $form->{cvar_module};
+
+  $form->{edit} = 0;
+  display_cvar_config_form();
+
+  $lxdebug->leave_sub();
+}
+
+sub edit_cvar_config {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  my $config = CVar->get_config('id' => $form->{id});
+
+  map { $form->{$_} = $config->{$_} } keys %{ $config };
+
+  $form->{edit} = 1;
+  display_cvar_config_form();
+
+  $lxdebug->leave_sub();
+}
+
+sub save {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  $form->isblank('name',        $locale->text('The name is missing.'));
+  $form->isblank('description', $locale->text('The description is missing.'));
+  $form->isblank('options',     $locale->text('The option field is empty.')) if ($form->{type} eq 'select');
+
+  if ($form->{name} !~ /^[a-z][a-z0-9_]*$/i) {
+    $form->error($locale->text('The name must only consist of letters, numbers and underscores and start with a letter.'));
+  }
+
+  if (($form->{type} eq 'number') && ($form->{default_value} ne '')) {
+    $form->{default_value} = $form->parse_amount(\%myconfig, $form->{default_value});
+  }
+
+  $form->{included_by_default} = $form->{inclusion} eq 'yes_default_on';
+  $form->{includeable}         = $form->{inclusion} ne 'no';
+
+  CVar->save_config('module' => $form->{module},
+                    'config' => $form);
+
+  $form->{MESSAGE} = $locale->text('The custom variable has been saved.');
+
+  list_cvar_configs();
+
+  $lxdebug->leave_sub();
+}
+
+sub delete {
+  $lxdebug->enter_sub();
+
+  CVar->delete_config('id' => $form->{id});
+
+  $form->{MESSAGE} = $locale->text('The custom variable has been deleted.');
+
+  list_cvar_configs();
+
+  $lxdebug->leave_sub();
+}
+
+sub display_cvar_config_form {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  my @types = map { { 'type' => $_, 'type_tr' => $translations{$_} } } @types;
+
+  if (($form->{type} eq 'number') && ($form->{default_value} ne '')) {
+    $form->{default_value} = $form->format_amount(\%myconfig, $form->{default_value});
+  }
+
+  $form->{title} = $form->{edit} ? $locale->text("Edit custom variable") : $locale->text("Add custom variable");
+
+  $form->header();
+  print $form->parse_html_template("amcvar/display_cvar_config_form", { 'TYPES' => \@types });
+
+  $lxdebug->leave_sub();
+}
+
+sub swap_cvar_configs {
+  $lxdebug->enter_sub();
+
+  AM->swap_sortkeys(\%myconfig, $form, 'custom_variable_configs');
+
+  list_cvar_configs();
+
+  $lxdebug->leave_sub();
+}
+
+1;
index 673aa09..d4c5230 100644 (file)
@@ -42,6 +42,7 @@ use CGI::Ajax;
 use POSIX qw(strftime);
 
 use SL::CT;
+use SL::CVar;
 use SL::ReportGenerator;
 
 require "bin/mozilla/common.pl";
@@ -80,8 +81,15 @@ sub search {
   $form->get_lists("business_types" => "ALL_BUSINESS_TYPES");
   $form->{SHOW_BUSINESS_TYPES} = scalar @{ $form->{ALL_BUSINESS_TYPES} } > 0;
 
-  $form->{title} = $form->{IS_CUSTOMER} ? $locale->text('Customers') : $locale->text('Vendors');
-  $form->{fokus} = 'Form.name';
+  $form->{CUSTOM_VARIABLES}                  = CVar->get_configs('module' => 'CT');
+  ($form->{CUSTOM_VARIABLES_FILTER_CODE},
+   $form->{CUSTOM_VARIABLES_INCLUSION_CODE}) = CVar->render_search_options('variables'      => $form->{CUSTOM_VARIABLES},
+                                                                           'include_prefix' => 'l_',
+                                                                           'include_value'  => 'Y');
+
+  $form->{jsscript} = 1;
+  $form->{title}    = $form->{IS_CUSTOMER} ? $locale->text('Customers') : $locale->text('Vendors');
+  $form->{fokus}    = 'Form.name';
 
   $form->header();
   print $form->parse_html_template('ct/search');
@@ -98,6 +106,8 @@ sub list_names {
 
   CT->search(\%myconfig, \%$form);
 
+  my $cvar_configs = CVar->get_configs('module' => 'CT');
+
   my @options;
   if ($form->{status} eq 'all') {
     push @options, $locale->text('All');
@@ -125,6 +135,11 @@ sub list_names {
     'ordnumber', 'quonumber'
   );
 
+  my @includeable_custom_variables = grep { $_->{includeable} } @{ $cvar_configs };
+  my %column_defs_cvars            = map { +"cvar_$_->{name}" => { 'text' => $_->{description} } } @includeable_custom_variables;
+
+  push @columns, map { "cvar_$_->{name}" } @includeable_custom_variables;
+
   my %column_defs = (
     'id'                => { 'text' => $locale->text('ID'), },
     "$form->{db}number" => { 'text' => $form->{IS_CUSTOMER} ? $locale->text('Customer Number') : $locale->text('Vendor Number'), },
@@ -141,6 +156,7 @@ sub list_names {
     'invnumber'         => { 'text' => $locale->text('Invoice'), },
     'ordnumber'         => { 'text' => $form->{IS_CUSTOMER} ? $locale->text('Sales Order') : $locale->text('Purchase Order'), },
     'quonumber'         => { 'text' => $form->{IS_CUSTOMER} ? $locale->text('Quotation')   : $locale->text('Request for Quotation'), },
+    %column_defs_cvars,
   );
 
   map { $column_defs{$_}->{visible} = $form->{"l_$_"} eq 'Y' } @columns;
@@ -183,6 +199,12 @@ sub list_names {
 
   $report->set_sort_indicator($form->{sort}, 1);
 
+  CVar->add_custom_variables_to_report('module'         => 'CT',
+                                       'trans_id_field' => 'id',
+                                       'configs'        => $cvar_configs,
+                                       'column_defs'    => \%column_defs,
+                                       'data'           => $form->{CT});
+
   my $previous_id;
 
   foreach my $ref (@{ $form->{CT} }) {
@@ -273,6 +295,12 @@ sub form_header {
   map { $form->{"MB_$_"} = [ map +{ id => $_, description => $_ }, @{ $form->{$_} } ] } qw(TITLES GREETINGS COMPANY_GREETINGS DEPARTMENT);
 ## /LINET
 
+  $form->{CUSTOM_VARIABLES} = CVar->get_custom_variables('module' => 'CT', 'trans_id' => $form->{id});
+
+  CVar->render_inputs('variables' => $form->{CUSTOM_VARIABLES}) if (scalar @{ $form->{CUSTOM_VARIABLES} });
+
+  $main::lxdebug->dump(0, "cvar", $form->{CUSTOM_VARIABLES});
+
   $form->header;
   print $form->parse_html_template('ct/form_header');
 
index 771e390..e331ff7 100644 (file)
@@ -37,6 +37,7 @@ use CGI;
 use CGI::Ajax;
 use List::Util qw(max first);
 
+use SL::CVar;
 use SL::Common;
 use SL::CT;
 use SL::IC;
@@ -1412,7 +1413,7 @@ sub print_form {
     $form->{language} = "_" . $form->{language};
   }
 
-  # Format dates.
+  # Format dates and numbers.
   format_dates($output_dateformat, $output_longdates,
                qw(invdate orddate quodate pldate duedate reqdate transdate
                   shippingdate deliverydate validitydate paymentdate
@@ -1448,6 +1449,16 @@ sub print_form {
                    grep({ /^qty_\d+$/
                         } keys(%{$form})));
 
+  my ($cvar_date_fields, $cvar_number_fields) = CVar->get_field_format_list('module' => 'CT', 'prefix' => 'vc_');
+
+  if (scalar @{ $cvar_date_fields }) {
+    format_dates($output_dateformat, $output_longdates, @{ $cvar_date_fields });
+  }
+
+  while (my ($precision, $field_list) = each %{ $cvar_number_fields }) {
+    reformat_numbers($output_numberformat, $precision, @{ $field_list });
+  }
+
   $form->{IN} = "$form->{formname}$form->{language}${printer_code}.html";
   if ($form->{format} eq 'postscript') {
     $form->{postscript} = 1;
index b9ca939..c05b9b2 100644 (file)
@@ -81,6 +81,9 @@ td {
 
     <li><a href="dokumentenvorlagen-und-variablen.html#invoice_zahlungen">
       Variablen f&uuml;r die Zahlungseing&auml;nge</a></li>
+
+    <li><a href="dokumentenvorlagen-und-variablen.html#benutzerdefinierte_variablen_vc">
+      Benutzerdefinierte Kunden- und Lieferantenvariablen</a></li>
    </ol>
   </li>
 
@@ -817,6 +820,22 @@ td {
   </table>
  </p>
 
+ <h3><a name="benutzerdefinierte_variablen_vc">
+   Benutzerdefinierte Kunden- und Lieferantenvariablen:</a></h3>
+
+ <p>
+  Die vom Benutzer definierten Variablen f&uuml;r Kunden und
+  Lieferanten stehen beim Ausdruck von Einkaufs- und Verkaufsbelegen
+  ebenfalls zur Verf&uuml;gung. Ihre Namen setzen sich aus dem
+  Pr&auml;fix <code>vc_cvar_</code> und dem vom Benutzer festgelegten
+  Variablennamen zusammen.</p>
+
+ <p>Beispiel: Der Benutzer hat eine Variable
+  namens <code>number_of_employees</code> definiert, die die Anzahl
+  der Mitarbeiter des Unternehmens enth&auml;lt. Diese Variable steht
+  dann unter dem Namen <code>vc_cvar_number_of_employees</code> zur
+  Verf&uuml;gung.</p>
+
  <small><a href="dokumentenvorlagen-und-variablen.html#inhaltsverzeichnis">
    zum Inhaltsverzeichnis</a></small><br>
  <hr>
index 91e5a58..ff7bdbe 100644 (file)
@@ -98,6 +98,7 @@ $self->{texts} = {
   'Add Buchungsgruppe'          => 'Buchungsgruppe erfassen',
   'Add Business'                => 'Kunden-/Lieferantentyp erfassen',
   'Add Credit Note'             => 'Gutschrift erfassen',
+  'Add Custom Variable'         => 'Benutzerdefinierte Variable erfassen',
   'Add Customer'                => 'Kunde erfassen',
   'Add Department'              => 'Abteilung erfassen',
   'Add Dunning'                 => 'Mahnung erzeugen',
@@ -127,6 +128,7 @@ $self->{texts} = {
   'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
   'Add a new group'             => 'Neue Gruppe erfassen',
   'Add and edit %s'             => '%s hinzuf&uuml;gen und bearbeiten',
+  'Add custom variable'         => 'Benutzerdefinierte Variable erfassen',
   'Add to group'                => 'Zu Gruppe hinzufügen',
   'Add unit'                    => 'Einheit hinzuf&uuml;gen',
   'Address'                     => 'Adresse',
@@ -144,6 +146,7 @@ $self->{texts} = {
   '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',
+  'Annotations'                 => 'Anmerkungen',
   'Ansprechpartner'             => 'Ansprechpartner',
   'Application Error. No Format given' => 'Fehler in der Anwendung. Das Ausgabeformat fehlt.',
   'Application Error. Wrong Format' => 'Fehler in der Anwendung. Falsches Format: ',
@@ -208,6 +211,7 @@ aktualisieren wollen?',
   'Bis Konto: '                 => 'bis Konto: ',
   'Body:'                       => 'Text:',
   'Books are open'              => 'Die Bücher sind geöffnet.',
+  'Boolean variables: If the default value is non-empty then the checkbox will be checked by default and unchecked otherwise.' => 'Ja/Nein-Variablen: Wenn der Standardwert nicht leer ist, so wird die Checkbox standardm&auml;&szlig;ig angehakt.',
   'Both'                        => 'Sowohl als auch',
   'Bottom'                      => 'Unten',
   'Bought'                      => 'Gekauft',
@@ -337,6 +341,7 @@ aktualisieren wollen?',
   'Current / Next Level'        => 'Aktuelles / Nächstes Mahnlevel',
   'Current Earnings'            => 'Gewinn',
   'Current unit'                => 'Aktuelle Einheit',
+  'Custom Variables'            => 'Benutzerdefinierte Variablen',
   'Customer'                    => 'Kunde',
   'Customer Number'             => 'Kundennummer',
   'Customer Order Number'       => 'Bestellnummer des Kunden',
@@ -350,6 +355,7 @@ aktualisieren wollen?',
   'Customername'                => 'Kundenname',
   'Customernumberinit'          => 'Kunden-/Lieferantennummernkreis',
   'Customers'                   => 'Kunden',
+  'Customers and Vendors'       => 'Kunden und Lieferanten',
   'Customized Report'           => 'Vorgewählte Zeiträume',
   'DATEV - Export Assistent'    => 'DATEV-Exportassistent',
   'DATEV Angaben'               => 'DATEV-Angaben',
@@ -374,6 +380,7 @@ aktualisieren wollen?',
   'Date'                        => 'Datum',
   'Date Format'                 => 'Datumsformat',
   'Date Paid'                   => 'Zahlungsdatum',
+  'Date and timestamp variables: If the default value equals \'NOW\' then the current date/current timestamp will be used. Otherwise the default value is copied as-is.' => 'Datums- und Uhrzeitvariablen: Wenn der Standardwert \'NOW\' ist, so wird das aktuelle Datum/die aktuelle Uhrzeit eingef&uuml;gt. Andernfalls wird der Standardwert so wie er ist benutzt.',
   'Date missing!'               => 'Datum fehlt!',
   'Datevautomatik'              => 'Datevexport',
   'Datum von'                   => 'Datum von',
@@ -390,6 +397,7 @@ aktualisieren wollen?',
   'Default output medium'       => 'Standardausgabekanal',
   'Default printer'             => 'Standarddrucker',
   'Default template format'     => 'Standardvorlagenformat',
+  'Default value'               => 'Standardwert',
   'Defaults saved.'             => 'Die Standardeinstellungen wurden gespeichert.',
   'Delete'                      => 'Löschen',
   'Delete Account'              => 'Konto löschen',
@@ -496,6 +504,7 @@ aktualisieren wollen?',
   'Edit Vendor'                 => 'Lieferant editieren',
   'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
   'Edit and delete a group'     => 'Gruppen bearbeiten und l&ouml;schen',
+  'Edit custom variable'        => 'Benutzerdefinierte Variable bearbeiten',
   'Edit file'                   => 'Datei bearbeiten',
   'Edit group '                 => 'Gruppe bearbeiten',
   'Edit group membership'       => 'Gruppenmitgliedschaften bearbeiten',
@@ -563,6 +572,7 @@ aktualisieren wollen?',
   'Form details (second row)'   => 'Formulardetails (zweite Positionszeile)',
   'Formula'                     => 'Formel',
   'Free report period'          => 'Freier Zeitraum',
+  'Free-form text'              => 'Textzeile',
   'Fristsetzung'                => 'Fristsetzung',
   'From'                        => 'Von',
   'Full Access'                 => 'Vollzugriff',
@@ -616,6 +626,7 @@ aktualisieren wollen?',
   'Include column headings'     => 'Spalten&uuml;berschriften erzeugen',
   'Include in Report'           => 'In Bericht aufnehmen',
   'Include in drop-down menus'  => 'In Aufklappmenü aufnehmen',
+  'Includeable in reports'      => 'In Berichten anzeigbar',
   'Income Statement'            => 'GuV',
   'Income accno'                => 'Erl&ouml;skonto',
   'Incoming Payments'           => 'Zahlungseingänge',
@@ -713,6 +724,7 @@ aktualisieren wollen?',
   'List Accounting Groups'      => 'Buchungsgruppen anzeigen',
   'List Accounts'               => 'Konten anzeigen',
   'List Businesses'             => 'Kunden-/Lieferantentypen anzeigen',
+  'List Custom Variables'       => 'Benutzerdefinierte Variablen anzeigen',
   'List Departments'            => 'Abteilungen anzeigen',
   'List Groups'                 => 'Warengruppen anzeigen',
   'List Languages'              => 'Sprachen anzeigen',
@@ -724,6 +736,7 @@ aktualisieren wollen?',
   'List Printer'                => 'Drucker anzeigen',
   'List Tax'                    => 'Bearbeiten',
   'List Transactions'           => 'Buchungsliste',
+  'List of custom variables'    => 'Liste der benutzerdefinierten Variablen',
   'Load draft'                  => 'Entwurf laden',
   'Local Tax Office Preferences' => 'Angaben zum Finanzamt',
   'Lock System'                 => 'System sperren',
@@ -840,6 +853,7 @@ aktualisieren wollen?',
   'Number missing in Row'       => 'Nummer fehlt in Zeile',
   'Number of copies'            => 'Anzahl Kopien',
   'Number pages'                => 'Seiten nummerieren',
+  'Number variables: \'PRECISION=n\' forces numbers to be shown with exactly n decimal places.' => 'Zahlenvariablen: Mit \'PRECISION=n\' erzwingt man, dass Zahlen mit n Nachkommastellen formatiert werden.',
   'OBE-Export erfolgreich!'     => 'OBE-Export erfolgreich!',
   'Obsolete'                    => 'Ungültig',
   'Oct'                         => 'Okt',
@@ -864,6 +878,7 @@ aktualisieren wollen?',
   'Ordered'                     => 'Vom Kunde bestellt',
   'Orientation'                 => 'Seitenformat',
   'Orphaned'                    => 'Nie benutzt',
+  'Other values are ignored.'   => 'Andere Eingaben werden ignoriert.',
   'Others'                      => 'Andere',
   'Otherwise all users will only have access to their own settings.' => 'Andernfalls haben alle Benutzer nur Zugriff auf ihre Benutzereinstellungen.',
   'Out of balance transaction!' => 'Buchung ist nicht ausgeglichen!',
@@ -1067,6 +1082,7 @@ aktualisieren wollen?',
   'Saving the file \'%s\' failed. OS error message: %s' => 'Das Speichern der Datei \'%s\' schlug fehl. Fehlermeldung des Betriebssystems: %s',
   'Screen'                      => 'Bildschirm',
   'Search Dunning'              => 'Mahnung suchen',
+  'Searchable'                  => 'Durchsuchbar',
   'Select'                      => 'auswählen',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
@@ -1079,6 +1095,8 @@ aktualisieren wollen?',
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
   'Select the chart of accounts in use' => 'Benutzten Kontenrahmen ausw&auml;hlen',
   'Select the checkboxes that match users to the groups they should belong to.' => 'W&auml;hlen Sie diejenigen Checkboxen aus, die die Benutzer zu den gew&uuml;schten Gruppen zuordnen.',
+  'Selection'                   => 'Auswahlbox',
+  'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => 'Auswahlboxen: Das Optionenfeld muss die f&uuml;r die Auswahl verf&uuml;gbaren Eintr&auml;ge enthalten. Die Eintr&auml;ge werden mit \'##\' voneinander getrennt. Beispiel: \'Fr&uuml;h##Normal##Sp&auml;t\'.',
   'Sell Price'                  => 'Verkaufspreis',
   'Send the backup via Email'   => 'Die Sicherungsdatei per Email verschicken',
   'Sep'                         => 'Sep',
@@ -1179,10 +1197,15 @@ aktualisieren wollen?',
   'Template database'           => 'Datenbankvorlage',
   'Templates'                   => 'Vorlagen',
   'Terms missing in row '       => '+Tage fehlen in Zeile ',
+  'Text field'                  => 'Textfeld',
+  'Text field variables: \'WIDTH=w HEIGHT=h\' sets the width and height of the text field. They default to 30 and 5 respectively.' => 'Textfelder: \'WIDTH=w HEIGHT=h\' setzen die Breite und die H&ouml;he des Textfeldes. Wenn nicht anders angegeben, so werden sie 30 Zeichen breit und f&uuml;nf Zeichen hoch dargestellt.',
+  'Text variables: \'MAXLENGTH=n\' sets the maximum entry length to \'n\'.' => 'Textzeilen: \'MAXLENGTH=n\' setzt eine Maximall&auml;nge von n Zeichen.',
+  'Text, text field and number variables: The default value will be used as-is.' => 'Textzeilen, Textfelder und Zahlenvariablen: Der Standardwert wird so wie er ist &uuml;bernommen.',
   '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 LDAP server "#1:#2" is unreachable. Please check config/authentication.pl.' => 'Der LDAP-Server "#1:#2" ist nicht erreichbar. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
   'The authentication configuration file &quot;config/authentication.pl&quot; does not exist. This Lx-Office installation has probably not been updated correctly yet. Please contact your administrator.' => 'Die Konfigurationsdatei f&uuml;r die Authentifizierung &quot;config/authentication.pl&quot; wurde nicht gefunden. Diese Lx-Office-Installation wurde vermutlich noch nicht vollst&auml;ndig aktualisiert oder eingerichtet. Bitte wenden Sie sich an Ihren Administrator.',
   'The authentication database is not reachable at the moment. Either it hasn\'t been set up yet or the database server might be down. Please contact your administrator.' => 'Die Authentifizierungsdatenbank kann momentan nicht erreicht werden. Entweder wurde sie noch nicht eingerichtet, oder der Datenbankserver antwortet nicht. Bitte wenden Sie sich an Ihren Administrator.',
+  'The available options depend on the varibale type:' => 'Die verf&uuml;gbaren Optionen h&auml;ngen vom Variablentypen ab:',
   'The backup you upload here has to be a file created with &quot;pg_dump -o -Ft&quot;.' => 'Die von Ihnen hochzuladende Sicherungsdatei muss mit dem Programm und den Parametern &quot;pg_dump -o -Ft&quot; erstellt worden sein.',
   '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&ouml;scht werden.',
   'The base unit does not exist.' => 'Die Basiseinheit existiert nicht.',
@@ -1194,6 +1217,8 @@ aktualisieren wollen?',
   'The connection to the authentication database failed:' => 'Die Verbindung zur Authentifizierungsdatenbank schlug fehl:',
   'The connection to the template database failed:' => 'Die Verbindung zur Vorlagendatenbank schlug fehl:',
   'The creation of the authentication database failed:' => 'Das Anlegen der Authentifizierungsdatenbank schlug fehl:',
+  'The custom variable has been deleted.' => 'Die benutzerdefinierte Variable wurde gel&ouml;scht.',
+  'The custom variable has been saved.' => 'Die benutzerdefinierte Variable wurde gespeichert.',
   'The database [% HTML.escape(db) %] has been successfully deleted.' => 'Die Datenbank [% HTML.escape(db) %] wurde erfolgreich gel&ouml;scht.',
   'The database for user management and authentication does not exist. You can create let Lx-Office create it with the following parameters:' => 'Die Datenbank zur Verwaltung der Benutzerdaten und zur Authentifizierung existiert nicht. Sie k&ouml;nnen Lx-Office diese Datenbank mit den folgenden Parametern anlegen lassen:',
   'The database update/creation did not succeed. The file [% HTML.escape(file) %] contained the following error:' => 'Die Datenbankaktualisierung/erstellung schlug fehl. Die Datei [% HTML.escape(file) %] enthielt den folgenden Fehler:',
@@ -1203,6 +1228,9 @@ aktualisieren wollen?',
   'The dataset backup has been sent via email to [% HTML.escape(to) %].' => 'Die Datenbanksicherung wurde per Email an [% HTML.escape(to) %] verschickt.',
   'The dataset has to exist before a restoration can be started.' => 'Die Datenbank muss vor der Wiederherstellung bereits angelegt worden sein.',
   'The dataset name is missing.' => 'Der Datenbankname fehlt.',
+  'The default value depends on the variable type:' => 'Die Bedeutung des Standardwertes h&auml;ngt vom Variablentypen ab:',
+  'The description is missing.' => 'Die Beschreibung fehlt.',
+  'The description is shown on the form. Chose something short and descriptive.' => 'Die Beschreibung wird in der jeweiligen Maske angezeigt. Sie sollte kurz und pr&auml;gnant sein.',
   'The directory "%s" could not be created:\n%s' => 'Das Verzeichnis "%s" konnte nicht erstellt werden:\n%s',
   'The directory %s does not exist.' => 'Das Verzeichnis %s existiert nicht.',
   'The dunning process started' => 'Der Mahnprozess ist gestartet.',
@@ -1229,7 +1257,9 @@ aktualisieren wollen?',
   'The name in row %d has already been used before.' => 'Der Name in Zeile %d wurde vorher bereits benutzt.',
   'The name is missing in row %d.' => 'Der Name fehlt in Zeile %d.',
   'The name is missing.'        => 'Der Name fehlt.',
+  'The name must only consist of letters, numbers and underscores and start with a letter.' => 'Der Name darf nur aus Buchstaben (keine Umlaute), Ziffern und Unterstrichen bestehen und muss mit einem Buchstaben beginnen.',
   'The old file containing the user information is still present (&quot;[% HTML.escape(memberfile) %]&quot;). Do you want to migrate these users into the database? If not then you will not be able to log in with any of the users present in the old file. ' => 'Die alte Datei mit den Benutzerdaten existiert in dieser Installation noch immer (&quot;[% HTML.escape(memberfile) %]&quot;). Wollen Sie diese Benutzer in die neue Authentifizierungsdatenbank migrieren lassen? Falls nicht, so werden Sie sich nicht mehr mit den Benutzerdaten aus der alten Mitgliedsdatei anmelden k&ouml;nnen.',
+  'The option field is empty.'  => 'Das Optionsfeld ist leer.',
   'The pg_dump process could not be started.' => 'Der pg_dump-Prozess konnte nicht gestartet werden.',
   'The pg_restore process could not be started.' => 'Der pg_restore-Prozess konnte nicht gestartet werden.',
   'The preferred one is to install packages provided by your operating system distribution (e.g. Debian or RPM packages).' => 'Die bevorzugte Art, ein Perl-Modul zu installieren, ist durch Installation eines von Ihrem Betriebssystem zur Verf&uuml;gung gestellten Paketes (z.B. Debian-Pakete oder RPM).',
@@ -1248,6 +1278,7 @@ aktualisieren wollen?',
   'The user has been removed from this group.' => 'Der Benutzer wurde aus der Gruppe entfernt.',
   'The user is a member in the following group(s):' => 'Der Benutzer ist Mitglied in den folgenden Gruppen:',
   'The user migration process is complete.' => 'Der Prozess der Benutzerdatenmigration ist abgeschlossen.',
+  'The variable name must only consist of letters, numbers and underscores. It must begin with a letter. Example: send_christmas_present' => 'Der Variablenname darf nur aus Zeichen (keine Umlaute), Ziffern und Unterstrichen bestehen. Er muss mit einem Buchstaben beginnen. Beispiel: weihnachtsgruss_verschicken',
   'There are four tax zones.'   => 'Es gibt vier Steuerzonen.',
   'There are still entries in the database for which no unit has been assigned.' => 'Es gibt noch Eintr&auml;ge in der Datenbank, f&uuml;r die keine Einheit zugeordnet ist.',
   'There are usually three ways to install Perl modules.' => 'Es gibt normalerweise drei Arten, ein Perlmodul zu installieren.',
@@ -1262,6 +1293,7 @@ aktualisieren wollen?',
   'This upgrade script tries to map all existing parts in the database to the newly created Buchungsgruppen.' => 'Dieses Upgradescript versucht, bei allen bestehenden Artikeln neu erstellte Buchungsgruppen zuzuordnen.',
   '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.',
   'This vendor number is already in use.' => 'Diese Lieferantennummer wird bereits verwendet.',
+  'Timestamp'                   => 'Uhrzeit',
   'Title'                       => 'Titel',
   'To'                          => 'An',
   'To (email)'                  => 'An',
@@ -1369,6 +1401,8 @@ aktualisieren wollen?',
   'Yearly'                      => 'jährlich',
   'Yearly taxreport not yet implemented' => 'Jährlicher Steuerreport für dieses Ausgabeformat noch nicht implementiert',
   'Yes'                         => 'Ja',
+  'Yes, included by default'    => 'Ja, standardm&auml;&szlig;ig an',
+  'Yes/No (Checkbox)'           => 'Ja/Nein (Checkbox)',
   'You are logged out!'         => 'Auf Wiedersehen!',
   'You can also create new units now.' => 'Sie k&ouml;nnen jetzt auch neue Einheiten anlegen.',
   'You can create a missing dataset by going back and chosing &quot;Create Dataset&quot;.' => 'Sie k&ouml;nnen eine fehlende Datenbank erstellen, indem Sie jetzt zu&uuml;ck gehen und den Punkt &quot;Datenbank anlegen&quot; w&auml;hlen.',
diff --git a/locale/de/amcvar b/locale/de/amcvar
new file mode 100644 (file)
index 0000000..07d51f1
--- /dev/null
@@ -0,0 +1,174 @@
+$self->{texts} = {
+  'ADDED'                       => 'Hinzugefügt',
+  'AP'                          => 'Einkauf',
+  'AR'                          => 'Verkauf',
+  'Add custom variable'         => 'Benutzerdefinierte Variable erfassen',
+  'Address'                     => 'Adresse',
+  'Advance turnover tax return' => 'Umsatzsteuervoranmeldung',
+  'All reports'                 => 'Alle Berichte (Konten&uuml;bersicht, Saldenbilanz, GuV, BWA, Bilanz, Projektbuchungen)',
+  'Attempt to call an undefined sub named \'%s\'' => 'Es wurde versucht, eine nicht definierte Unterfunktion namens \'%s\' aufzurufen.',
+  'Bcc'                         => 'Bcc',
+  'Bin List'                    => 'Lagerliste',
+  'Binding to the LDAP server as "#1" failed. Please check config/authentication.pl.' => 'Die Anmeldung am LDAP-Server als "#1" schlug fehl. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'CANCELED'                    => 'Storniert',
+  'Cc'                          => 'Cc',
+  'Change Lx-Office installation settings (all menu entries beneath \'System\')' => 'Ver&auml;ndern der Lx-Office-Installationseinstellungen (Men&uuml;punkte unterhalb von \'System\')',
+  'Confirmation'                => 'Auftragsbestätigung',
+  'Contact'                     => 'Kontakt',
+  'Create and edit RFQs'        => 'Lieferantenanfragen erfassen und bearbeiten',
+  'Create and edit customers and vendors' => 'Kunden und Lieferanten erfassen und bearbeiten',
+  'Create and edit dunnings'    => 'Mahnungen erfassen und bearbeiten',
+  'Create and edit invoices and credit notes' => 'Rechnungen und Gutschriften erfassen und bearbeiten',
+  'Create and edit parts, services, assemblies' => 'Artikel, Dienstleistungen, Erzeugnisse erfassen und bearbeiten',
+  'Create and edit projects'    => 'Projekte erfassen und bearbeiten',
+  'Create and edit purchase delivery orders' => 'Lieferscheine von Lieferanten erfassen und bearbeiten',
+  'Create and edit purchase orders' => 'Lieferantenauftr&auml;ge erfassen und bearbeiten',
+  'Create and edit sales delivery orders' => 'Lieferscheine f&uuml;r Kunden erfassen und bearbeiten',
+  'Create and edit sales orders' => 'Auftragsbest&auml;tigungen erfassen und bearbeiten',
+  'Create and edit sales quotations' => 'Angebote erfassen und bearbeiten',
+  'Create and edit vendor invoices' => 'Eingangsrechnungen erfassen und bearbeiten',
+  'Credit Note'                 => 'Gutschrift',
+  'Customer Number'             => 'Kundennummer',
+  'Customer details'            => 'Kundendetails',
+  'DATEV Export'                => 'DATEV-Export',
+  'DELETED'                     => 'Gelöscht',
+  'DUNNING STARTED'             => 'Mahnprozess gestartet',
+  'Dataset upgrade'             => 'Datenbankaktualisierung',
+  'Date'                        => 'Datum',
+  'Dependency loop detected:'   => 'Schleife in den Abh&auml;ngigkeiten entdeckt:',
+  'Directory'                   => 'Verzeichnis',
+  'ELSE'                        => 'Zusatz',
+  'Edit custom variable'        => 'Benutzerdefinierte Variable bearbeiten',
+  'Enter longdescription'       => 'Langtext eingeben',
+  'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
+  'File'                        => 'Datei',
+  'Free-form text'              => 'Textzeile',
+  'General ledger and cash'     => 'Finanzbuchhaltung und Zahlungsverkehr',
+  'History'                     => 'Historie',
+  'Invoice'                     => 'Rechnung',
+  'List of custom variables'    => 'Liste der benutzerdefinierten Variablen',
+  'MAILED'                      => 'Gesendet',
+  'Manage license keys'         => 'Lizenzschl&uuml;ssel verwalten',
+  'Mark as paid?'               => 'Als bezahlt markieren?',
+  'Marked as paid'              => 'Als bezahlt markiert',
+  'Master Data'                 => 'Stammdaten',
+  'May set the BCC field when sending emails' => 'Beim Verschicken von Emails das Feld \'BCC\' setzen',
+  'Message'                     => 'Nachricht',
+  'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
+  'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
+  'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
+  'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
+  'Name'                        => 'Name',
+  'No'                          => 'Nein',
+  'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
+  '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 customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
+  'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
+  'Number'                      => 'Nummer',
+  'Others'                      => 'Andere',
+  'PAYMENT POSTED'              => 'Rechung gebucht',
+  'POSTED'                      => 'Gebucht',
+  'POSTED AS NEW'               => 'Als neu gebucht',
+  'PRINTED'                     => 'Gedruckt',
+  'Packing List'                => 'Lieferschein',
+  'Pick List'                   => 'Sammelliste',
+  'Please enter values'         => 'Bitte Werte eingeben',
+  'Proforma Invoice'            => 'Proformarechnung',
+  'Purchase Order'              => 'Lieferantenauftrag',
+  'Quotation'                   => 'Angebot',
+  'RFQ'                         => 'Anfrage',
+  'Receipt, payment, reconciliation' => 'Zahlungseingang, Zahlungsausgang, Kontenabgleich',
+  'Reports'                     => 'Berichte',
+  'SAVED'                       => 'Gespeichert',
+  'SAVED FOR DUNNING'           => 'Gespeichert',
+  'SCREENED'                    => 'Angezeigt',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
+  'Selection'                   => 'Auswahlbox',
+  'Storno Invoice'              => 'Stornorechnung',
+  'Storno Packing List'         => 'Stornolieferschein',
+  'Subject'                     => 'Betreff',
+  'Text field'                  => 'Textfeld',
+  '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 LDAP server "#1:#2" is unreachable. Please check config/authentication.pl.' => 'Der LDAP-Server "#1:#2" ist nicht erreichbar. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'The config file "config/authentication.pl" contained invalid Perl code:' => 'Die Konfigurationsdatei "config/authentication.pl" enthielt ung&uuml;tigen Perl-Code:',
+  'The config file "config/authentication.pl" was not found.' => 'Die Konfigurationsdatei "config/authentication.pl" wurde nicht gefunden.',
+  'The connection to the LDAP server cannot be encrypted (SSL/TLS startup failure). Please check config/authentication.pl.' => 'Die Verbindung zum LDAP-Server kann nicht verschl&uuml;sselt werden (Fehler bei SSL/TLS-Initialisierung). Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'The connection to the authentication database failed:' => 'Die Verbindung zur Authentifizierungsdatenbank schlug fehl:',
+  'The connection to the template database failed:' => 'Die Verbindung zur Vorlagendatenbank schlug fehl:',
+  'The creation of the authentication database failed:' => 'Das Anlegen der Authentifizierungsdatenbank schlug fehl:',
+  'The custom variable has been deleted.' => 'Die benutzerdefinierte Variable wurde gel&ouml;scht.',
+  'The custom variable has been saved.' => 'Die benutzerdefinierte Variable wurde gespeichert.',
+  'The description is missing.' => 'Die Beschreibung fehlt.',
+  'The name is missing.'        => 'Der Name fehlt.',
+  'The name must only consist of letters, numbers and underscores and start with a letter.' => 'Der Name darf nur aus Buchstaben (keine Umlaute), Ziffern und Unterstrichen bestehen und muss mit einem Buchstaben beginnen.',
+  'The option field is empty.'  => 'Das Optionsfeld ist leer.',
+  'Timestamp'                   => 'Uhrzeit',
+  'To (email)'                  => 'An',
+  'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
+  'Trying to call a sub without a name' => 'Es wurde versucht, eine Unterfunktion ohne Namen aufzurufen.',
+  'Unit'                        => 'Einheit',
+  'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
+  'Vendor details'              => 'Lieferantendetails',
+  'Yes'                         => 'Ja',
+  'Yes/No (Checkbox)'           => 'Ja/Nein (Checkbox)',
+  'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
+  '[email]'                     => '[email]',
+  'bin_list'                    => 'Lagerliste',
+  'config/authentication.pl: Key "DB_config" is missing.' => 'config/authentication.pl: Das Schl&uuml;sselwort "DB_config" fehlt.',
+  'config/authentication.pl: Key "LDAP_config" is missing.' => 'config/authentication.pl: Der Schl&uuml;ssel "LDAP_config" fehlt.',
+  'config/authentication.pl: Missing parameters in "DB_config". Required parameters are "host", "db" and "user".' => 'config/authentication.pl: Fehlende Parameter in "DB_config". Ben&ouml;tigte Parameter sind "host", "db" und "user".',
+  'config/authentication.pl: Missing parameters in "LDAP_config". Required parameters are "host", "attribute" and "base_dn".' => 'config/authentication.pl: Fehlende Parameter in "LDAP_config". Ben&ouml;tigt werden "host", "attribute" und "base_dn".',
+  'customer'                    => 'Kunde',
+  'invoice'                     => 'Rechnung',
+  'no'                          => 'nein',
+  'packing_list'                => 'Versandliste',
+  'pick_list'                   => 'Entnahmeliste',
+  'proforma'                    => 'Proforma',
+  'purchase_order'              => 'Auftrag',
+  'request_quotation'           => 'Angebotsanforderung',
+  'sales_order'                 => 'Kundenauftrag',
+  'sales_quotation'             => 'Verkaufsangebot',
+  'vendor'                      => 'Lieferant',
+  'yes'                         => 'ja',
+};
+
+$self->{subs} = {
+  'E'                           => 'E',
+  'H'                           => 'H',
+  'NTI'                         => 'NTI',
+  'Q'                           => 'Q',
+  'add'                         => 'add',
+  'add_cvar_config'             => 'add_cvar_config',
+  'build_std_url'               => 'build_std_url',
+  'calculate_qty'               => 'calculate_qty',
+  'call_sub'                    => 'call_sub',
+  'cov_selection_internal'      => 'cov_selection_internal',
+  'delete'                      => 'delete',
+  'delivery_customer_selection' => 'delivery_customer_selection',
+  'display_cvar_config_form'    => 'display_cvar_config_form',
+  'edit'                        => 'edit',
+  'edit_cvar_config'            => 'edit_cvar_config',
+  'format_dates'                => 'format_dates',
+  'list_cvar_configs'           => 'list_cvar_configs',
+  'mark_as_paid_common'         => 'mark_as_paid_common',
+  'reformat_numbers'            => 'reformat_numbers',
+  'retrieve_partunits'          => 'retrieve_partunits',
+  'save'                        => 'save',
+  'set_longdescription'         => 'set_longdescription',
+  'show_history'                => 'show_history',
+  'show_vc_details'             => 'show_vc_details',
+  'swap_cvar_configs'           => 'swap_cvar_configs',
+  'vendor_selection'            => 'vendor_selection',
+  'erfassen'                    => 'add',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'speichern'                   => 'save',
+};
+
+1;
index 455c02f..c6877f3 100644 (file)
@@ -124,6 +124,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
index 6ed63b1..c4b7b96 100644 (file)
@@ -131,6 +131,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
index 26567de..0deefac 100644 (file)
@@ -77,6 +77,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
@@ -144,6 +145,7 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zero amount posting!'        => 'Buchung ohne Wert',
   '[email]'                     => '[email]',
index a5873ce..bc7e0a1 100644 (file)
@@ -75,6 +75,7 @@ $self->{texts} = {
   'Name'                        => 'Name',
   'Name missing!'               => 'Name fehlt!',
   'New contact'                 => 'Neuer Ansprechpartner',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
@@ -136,6 +137,7 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor saved!'               => 'Lieferant gespeichert!',
   'Vendors'                     => 'Lieferanten',
+  'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
index 74afbaa..2db8e02 100644 (file)
@@ -126,6 +126,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
@@ -224,6 +225,7 @@ $self->{texts} = {
   'Variable'                    => 'Variable',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor details'              => 'Lieferantendetails',
+  'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
   '[email]'                     => '[email]',
index 4a9c07f..5ecf7a9 100644 (file)
@@ -124,6 +124,7 @@ $self->{texts} = {
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'MwSt. inkl.'                 => 'MwSt. inkl.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
index 507a3ec..15515f2 100644 (file)
@@ -143,6 +143,7 @@ $self->{texts} = {
   'Model'                       => 'Modell',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
@@ -269,6 +270,7 @@ $self->{texts} = {
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor details'              => 'Lieferantendetails',
   'Weight'                      => 'Gewicht',
+  'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
   '[email]'                     => '[email]',
index 5e75bb4..15a5879 100644 (file)
@@ -102,6 +102,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
@@ -190,6 +191,7 @@ $self->{texts} = {
   'Variable'                    => 'Variable',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor details'              => 'Lieferantendetails',
+  'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
   '[email]'                     => '[email]',
index c891565..c16bf5d 100644 (file)
@@ -137,6 +137,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
index cdef5a5..2a286c8 100644 (file)
@@ -155,6 +155,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
index e61adfe..0bd5b00 100644 (file)
@@ -70,6 +70,7 @@ $self->{texts} = {
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
   'Name'                        => 'Name',
+  'No'                          => 'Nein',
   'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
   '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',
@@ -129,6 +130,7 @@ $self->{texts} = {
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
   'View License'                => 'Lizenz ansehen',
+  'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
   '[email]'                     => '[email]',
index 6304d86..fd59978 100644 (file)
@@ -11,6 +11,7 @@ $self->{texts} = {
   'Add Assembly'                => 'Erzeugnis erfassen',
   'Add Business'                => 'Kunden-/Lieferantentyp erfassen',
   'Add Credit Note'             => 'Gutschrift erfassen',
+  'Add Custom Variable'         => 'Benutzerdefinierte Variable erfassen',
   'Add Customer'                => 'Kunde erfassen',
   'Add Department'              => 'Abteilung erfassen',
   'Add Dunning'                 => 'Mahnung erzeugen',
@@ -61,8 +62,10 @@ $self->{texts} = {
   'Create and edit sales orders' => 'Auftragsbest&auml;tigungen erfassen und bearbeiten',
   'Create and edit sales quotations' => 'Angebote erfassen und bearbeiten',
   'Create and edit vendor invoices' => 'Eingangsrechnungen erfassen und bearbeiten',
+  'Custom Variables'            => 'Benutzerdefinierte Variablen',
   'Customer'                    => 'Kunde',
   'Customers'                   => 'Kunden',
+  'Customers and Vendors'       => 'Kunden und Lieferanten',
   'DATEV - Export Assistent'    => 'DATEV-Exportassistent',
   'DATEV Export'                => 'DATEV-Export',
   'Dataset upgrade'             => 'Datenbankaktualisierung',
@@ -91,6 +94,7 @@ $self->{texts} = {
   'List Accounting Groups'      => 'Buchungsgruppen anzeigen',
   'List Accounts'               => 'Konten anzeigen',
   'List Businesses'             => 'Kunden-/Lieferantentypen anzeigen',
+  'List Custom Variables'       => 'Benutzerdefinierte Variablen anzeigen',
   'List Departments'            => 'Abteilungen anzeigen',
   'List Groups'                 => 'Warengruppen anzeigen',
   'List Languages'              => 'Sprachen anzeigen',
index b8b71d9..09c3566 100644 (file)
@@ -10,6 +10,7 @@ $self->{texts} = {
   'Add Assembly'                => 'Erzeugnis erfassen',
   'Add Business'                => 'Kunden-/Lieferantentyp erfassen',
   'Add Credit Note'             => 'Gutschrift erfassen',
+  'Add Custom Variable'         => 'Benutzerdefinierte Variable erfassen',
   'Add Customer'                => 'Kunde erfassen',
   'Add Department'              => 'Abteilung erfassen',
   'Add Dunning'                 => 'Mahnung erzeugen',
@@ -60,8 +61,10 @@ $self->{texts} = {
   'Create and edit sales orders' => 'Auftragsbest&auml;tigungen erfassen und bearbeiten',
   'Create and edit sales quotations' => 'Angebote erfassen und bearbeiten',
   'Create and edit vendor invoices' => 'Eingangsrechnungen erfassen und bearbeiten',
+  'Custom Variables'            => 'Benutzerdefinierte Variablen',
   'Customer'                    => 'Kunde',
   'Customers'                   => 'Kunden',
+  'Customers and Vendors'       => 'Kunden und Lieferanten',
   'DATEV - Export Assistent'    => 'DATEV-Exportassistent',
   'DATEV Export'                => 'DATEV-Export',
   'Dataset upgrade'             => 'Datenbankaktualisierung',
@@ -90,6 +93,7 @@ $self->{texts} = {
   'List Accounting Groups'      => 'Buchungsgruppen anzeigen',
   'List Accounts'               => 'Konten anzeigen',
   'List Businesses'             => 'Kunden-/Lieferantentypen anzeigen',
+  'List Custom Variables'       => 'Benutzerdefinierte Variablen anzeigen',
   'List Departments'            => 'Abteilungen anzeigen',
   'List Groups'                 => 'Warengruppen anzeigen',
   'List Languages'              => 'Sprachen anzeigen',
index fe28f11..8f0d8d4 100644 (file)
--- a/menu.ini
+++ b/menu.ini
@@ -591,6 +591,29 @@ action=add_payment
 module=am.pl
 action=list_payment
 
+[System--Custom Variables]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[System--Custom Variables--Customers and Vendors]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[System--Custom Variables--Customers and Vendors--Add Custom Variable]
+module=amcvar.pl
+action=add_cvar_config
+cvar_module=CT
+
+[System--Custom Variables--Customers and Vendors--List Custom Variables]
+module=amcvar.pl
+action=list_cvar_configs
+cvar_module=CT
+
+
 #[System--Import Datanorm]
 #module=menu.pl
 #action=acc_menu
diff --git a/sql/Pg-upgrade2/custom_variables.sql b/sql/Pg-upgrade2/custom_variables.sql
new file mode 100644 (file)
index 0000000..884594a
--- /dev/null
@@ -0,0 +1,51 @@
+-- @tag: custom_variables
+-- @description: Benutzerdefinierte Variablen f&uuml;r beliebige Module. Hier nur f&uuml;r Kunden- und Lieferantenstammdaten implementiert.
+-- @depends: release_2_4_3
+CREATE SEQUENCE custom_variable_configs_id;
+CREATE TABLE custom_variable_configs (
+       id integer NOT NULL DEFAULT nextval('custom_variable_configs_id'),
+       name text,
+       description text,
+       type varchar(20),
+       module varchar(20),
+       default_value text,
+       options text,
+       searchable boolean,
+       includeable boolean,
+       included_by_default boolean,
+       sortkey integer,
+
+       itime timestamp DEFAULT now(),
+       mtime timestamp,
+
+       PRIMARY KEY (id)
+);
+
+CREATE TRIGGER mtime_custom_variable_configs
+    BEFORE UPDATE ON custom_variable_configs
+    FOR EACH ROW
+    EXECUTE PROCEDURE set_mtime();
+
+CREATE SEQUENCE custom_variables_id;
+CREATE TABLE custom_variables (
+       id integer NOT NULL DEFAULT nextval('custom_variables_id'),
+       config_id integer NOT NULL,
+       trans_id integer NOT NULL,
+
+       bool_value boolean,
+       timestamp_value timestamp,
+       text_value text,
+       number_value numeric(25,5),
+
+       itime timestamp DEFAULT now(),
+       mtime timestamp,
+
+       PRIMARY KEY (id),
+       FOREIGN KEY (config_id) REFERENCES custom_variable_configs (id)
+);
+
+CREATE TRIGGER mtime_custom_variables
+    BEFORE UPDATE ON custom_variables
+    FOR EACH ROW
+    EXECUTE PROCEDURE set_mtime();
+
diff --git a/templates/webpages/amcvar/display_cvar_config_form_de.html b/templates/webpages/amcvar/display_cvar_config_form_de.html
new file mode 100644 (file)
index 0000000..0bee90b
--- /dev/null
@@ -0,0 +1,117 @@
+[% USE HTML %]<body onload="document.Form.name.focus();">
+
+ <style type="text/css">
+  .small {
+    font-size: 0.75em;
+  }
+ </style>
+
+ <div class="listtop">[% title %]</div>
+
+ <form action="amcvar.pl" name="Form" method="post">
+
+  <p>
+   <table>
+    <tr>
+     <td align="right">Name<sup><span class="small">(1)</span></sup></td>
+     <td><input name="name" value="[% HTML.escape(name) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right">Beschreibung<sup><span class="small">(2)</span></sup></td>
+     <td><input name="description" value="[% HTML.escape(description) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right">Typ</td>
+     <td>
+      <select name="type">
+       [%- FOREACH row = TYPES %]
+       <option value="[% HTML.escape(row.type) %]"[% IF row.type == type %] selected[% END %]>[% HTML.escape(row.type_tr) %]</option>
+       [%- END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <td align="right">Standardwert<sup><span class="small">(3)</span></sup></td>
+     <td><input name="default_value" value="[% HTML.escape(default_value) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right">Optionen<sup><span class="small">(4)</span></sup></td>
+     <td><input name="options" value="[% HTML.escape(options) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right">Durchsuchbar<sup><span class="small"></span></sup></td>
+     <td>
+      <input type="radio" name="searchable" id="searchable_1" value="1"[% IF searchable %] checked[% END %]>
+      <label for="searchable_1">Ja</label>
+      <input type="radio" name="searchable" id="searchable_0" value="0"[% UNLESS searchable %] checked[% END %]>
+      <label for="searchable_0">Nein</label>
+     </td>
+    </tr>
+
+    <tr>
+     <td align="right">In Berichten anzeigbar<sup><span class="small"></span></sup></td>
+     <td>
+      <select name="inclusion">
+       <option value="no"[% UNLESS includeable %] selected[% END %]>Nein</option>
+       <option value="yes"[% IF includeable && !included_by_default %] selected[% END %]>Ja</option>
+       <option value="yes_default_on"[% IF included_by_default %] selected[% END %]>Ja, standardm&auml;&szlig;ig an</option>
+      </select>
+     </td>
+    </tr>
+   </table>
+  </p>
+
+  <input type="hidden" name="module" value="[% HTML.escape(module) %]">
+  <input type="hidden" name="id"     value="[% HTML.escape(id) %]">
+
+  <p>
+   <input type="submit" name="action" value="Speichern">
+   [%- IF id %]
+   <input type="submit" name="action" value="Löschen">
+   [%- END %]
+  </p>
+
+  <hr>
+
+  <h3>Anmerkungen</h3>
+
+  <p>
+   (1) Der Variablenname darf nur aus Zeichen (keine Umlaute), Ziffern und Unterstrichen bestehen. Er muss mit einem Buchstaben beginnen. Beispiel: weihnachtsgruss_verschicken
+  </p>
+
+  <p>
+   (2) Die Beschreibung wird in der jeweiligen Maske angezeigt. Sie sollte kurz und pr&auml;gnant sein.
+  </p>
+
+  <p>
+   (3) Die Bedeutung des Standardwertes h&auml;ngt vom Variablentypen ab:
+   <br>
+   <ul>
+    <li>Textzeilen, Textfelder und Zahlenvariablen: Der Standardwert wird so wie er ist &uuml;bernommen.</li>
+    <li>Ja/Nein-Variablen: Wenn der Standardwert nicht leer ist, so wird die Checkbox standardm&auml;&szlig;ig angehakt.</li>
+    <li>Datums- und Uhrzeitvariablen: Wenn der Standardwert 'NOW' ist, so wird das aktuelle Datum/die aktuelle Uhrzeit eingef&uuml;gt. Andernfalls wird der Standardwert so wie er ist benutzt.</li>
+   </ul>
+  </p>
+
+  <p>
+   (4) Die verf&uuml;gbaren Optionen h&auml;ngen vom Variablentypen ab:
+   <br>
+   <ul>
+    <li>Textzeilen: 'MAXLENGTH=n' setzt eine Maximall&auml;nge von n Zeichen.</li>
+    <li>Textfelder: 'WIDTH=w HEIGHT=h' setzen die Breite und die H&ouml;he des Textfeldes. Wenn nicht anders angegeben, so werden sie 30 Zeichen breit und f&uuml;nf Zeichen hoch dargestellt.</li>
+    <li>Zahlenvariablen: Mit 'PRECISION=n' erzwingt man, dass Zahlen mit n Nachkommastellen formatiert werden.</li>
+    <li>Auswahlboxen: Das Optionenfeld muss die f&uuml;r die Auswahl verf&uuml;gbaren Eintr&auml;ge enthalten. Die Eintr&auml;ge werden mit '##' voneinander getrennt. Beispiel: 'Fr&uuml;h##Normal##Sp&auml;t'.</li>
+   </ul>
+   <br>
+   Andere Eingaben werden ignoriert.
+  </p>
+
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/amcvar/display_cvar_config_form_master.html b/templates/webpages/amcvar/display_cvar_config_form_master.html
new file mode 100644 (file)
index 0000000..438758f
--- /dev/null
@@ -0,0 +1,132 @@
+[% USE HTML %]<body onload="document.Form.name.focus();">
+
+ <style type="text/css">
+  .small {
+    font-size: 0.75em;
+  }
+ </style>
+
+ <div class="listtop">[% title %]</div>
+
+ <form action="amcvar.pl" name="Form" method="post">
+
+  <p>
+   <table>
+    <tr>
+     <td align="right"><translate>Name</translate><sup><span class="small">(1)</span></sup></td>
+     <td><input name="name" value="[% HTML.escape(name) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right"><translate>Description</translate><sup><span class="small">(2)</span></sup></td>
+     <td><input name="description" value="[% HTML.escape(description) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right"><translate>Type</translate></td>
+     <td>
+      <select name="type">
+       [%- FOREACH row = TYPES %]
+       <option value="[% HTML.escape(row.type) %]"[% IF row.type == type %] selected[% END %]>[% HTML.escape(row.type_tr) %]</option>
+       [%- END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <td align="right"><translate>Default value</translate><sup><span class="small">(3)</span></sup></td>
+     <td><input name="default_value" value="[% HTML.escape(default_value) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right"><translate>Options</translate><sup><span class="small">(4)</span></sup></td>
+     <td><input name="options" value="[% HTML.escape(options) %]"></td>
+    </tr>
+
+    <tr>
+     <td align="right"><translate>Searchable</translate><sup><span class="small"></span></sup></td>
+     <td>
+      <input type="radio" name="searchable" id="searchable_1" value="1"[% IF searchable %] checked[% END %]>
+      <label for="searchable_1"><translate>Yes</translate></label>
+      <input type="radio" name="searchable" id="searchable_0" value="0"[% UNLESS searchable %] checked[% END %]>
+      <label for="searchable_0"><translate>No</translate></label>
+     </td>
+    </tr>
+
+    <tr>
+     <td align="right"><translate>Includeable in reports</translate><sup><span class="small"></span></sup></td>
+     <td>
+      <select name="inclusion">
+       <option value="no"[% UNLESS includeable %] selected[% END %]><translate>No</translate></option>
+       <option value="yes"[% IF includeable && !included_by_default %] selected[% END %]><translate>Yes</translate></option>
+       <option value="yes_default_on"[% IF included_by_default %] selected[% END %]><translate>Yes, included by default</translate></option>
+      </select>
+     </td>
+    </tr>
+   </table>
+  </p>
+
+  <input type="hidden" name="module" value="[% HTML.escape(module) %]">
+  <input type="hidden" name="id"     value="[% HTML.escape(id) %]">
+
+  <p>
+   <input type="submit" name="action" value="<translate>Save</translate>">
+   [%- IF id %]
+   <input type="submit" name="action" value="<translate>Delete</translate>">
+   [%- END %]
+  </p>
+
+  <hr>
+
+  <h3><translate>Annotations</translate></h3>
+
+  <p>
+   (1) <translate>The variable name must only consist of letters,
+    numbers and underscores. It must begin with a letter. Example:
+    send_christmas_present</translate>
+  </p>
+
+  <p>
+   (2) <translate>The description is shown on the form. Chose
+    something short and descriptive.</translate>
+  </p>
+
+  <p>
+   (3) <translate>The default value depends on the variable type:</translate>
+   <br>
+   <ul>
+    <li><translate>Text, text field and number variables: The default
+      value will be used as-is.</translate></li>
+    <li><translate>Boolean variables: If the default value is
+      non-empty then the checkbox will be checked by default and
+      unchecked otherwise.</translate></li>
+    <li><translate>Date and timestamp variables: If the default value
+      equals 'NOW' then the current date/current timestamp will be
+      used. Otherwise the default value is copied as-is.</translate></li>
+   </ul>
+  </p>
+
+  <p>
+   (4) <translate>The available options depend on the varibale
+    type:</translate>
+   <br>
+   <ul>
+    <li><translate>Text variables: 'MAXLENGTH=n' sets the maximum
+      entry length to 'n'.</translate></li>
+    <li><translate>Text field variables: 'WIDTH=w HEIGHT=h' sets the
+      width and height of the text field. They default to 30 and 5
+      respectively.</translate></li>
+    <li><translate>Number variables: 'PRECISION=n' forces numbers to
+      be shown with exactly n decimal places.</translate></li>
+    <li><translate>Selection fields: The option field must contain the
+      available options for the selection. Options are separated by
+      '##', for example 'Early##Normal##Late'.</translate></li>
+   </ul>
+   <br>
+   <translate>Other values are ignored.</translate>
+  </p>
+
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/amcvar/list_cvar_configs_de.html b/templates/webpages/amcvar/list_cvar_configs_de.html
new file mode 100644 (file)
index 0000000..018157d
--- /dev/null
@@ -0,0 +1,79 @@
+[% USE HTML %]<body>
+
+ [% IF MESSAGE %]<p>[% MESSAGE %]</p>[% END %]
+
+ <div class="listtop">[% title %]</div>
+
+ <p>
+  <table width="100%">
+   <tr>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="20%">Name</td>
+    <td class="listheading" width="20%">Beschreibung</td>
+    <td class="listheading" width="20%">Typ</td>
+    <td class="listheading" width="20%">Durchsuchbar</td>
+    <td class="listheading" width="20%">In Berichten anzeigbar</td>
+   </tr>
+
+   [%- FOREACH cfg = CONFIGS %]
+   <tr class="listrow[% loop.count % 2 %]">
+    <td>
+     [%- IF cfg.previous_id %]
+     <a href="amcvar.pl?action=swap_cvar_configs&module=[% HTML.url(module) %]&id1=[% HTML.url(cfg.previous_id) %]&id2=[% HTML.url(cfg.id) %]">
+      <img border="0" src="image/up.png"></a>
+     [%- END %]
+    </td>
+
+    <td>
+     [%- IF cfg.next_id %]
+     <a href="amcvar.pl?action=swap_cvar_configs&module=[% HTML.url(module) %]&id1=[% HTML.url(cfg.next_id) %]&id2=[% HTML.url(cfg.id) %]">
+      <img border="0" src="image/down.png"></a>
+     [%- END %]
+    </td>
+
+    <td>
+     <a href="amcvar.pl?action=edit_cvar_config&module=[% HTML.url(module) %]&id=[% HTML.url(cfg.id) %]&callback=[% HTML.url(callback) %]">
+      [% HTML.escape(cfg.name) %]
+     </a>
+    </td>
+
+    <td>[% HTML.escape(cfg.description) %]</td>
+    <td>[% HTML.escape(cfg.type_tr) %]</td>
+
+    <td>
+     [%- IF cfg.searchable %]
+     Ja
+     [%- ELSE %]
+     Nein
+     [%- END %]
+    </td>
+
+    <td>
+     [%- IF cfg.included_by_default %]
+     Ja, standardm&auml;&szlig;ig an
+     [%- ELSIF cfg.includeable %]
+     Ja
+     [%- ELSE %]
+     Nein
+     [%- END %]
+    </td>
+   </tr>
+   [%- END %]
+  </table>
+ </p>
+
+ <hr height="3">
+
+ <p>
+  <form method="post" action="amcvar.pl">
+   <input type="hidden" name="add_nextsub" value="add_cvar_config">
+   <input type="hidden" name="module" value="[% HTML.escape(module) %]">
+   <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+
+   <input type="submit" class="submit" name="action" value="Erfassen">
+  </form>
+ </p>
+
+</body>
+</html>
diff --git a/templates/webpages/amcvar/list_cvar_configs_master.html b/templates/webpages/amcvar/list_cvar_configs_master.html
new file mode 100644 (file)
index 0000000..f4d7c25
--- /dev/null
@@ -0,0 +1,79 @@
+[% USE HTML %]<body>
+
+ [% IF MESSAGE %]<p>[% MESSAGE %]</p>[% END %]
+
+ <div class="listtop">[% title %]</div>
+
+ <p>
+  <table width="100%">
+   <tr>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="20%"><translate>Name</translate></td>
+    <td class="listheading" width="20%"><translate>Description</translate></td>
+    <td class="listheading" width="20%"><translate>Type</translate></td>
+    <td class="listheading" width="20%"><translate>Searchable</translate></td>
+    <td class="listheading" width="20%"><translate>Includeable in reports</translate></td>
+   </tr>
+
+   [%- FOREACH cfg = CONFIGS %]
+   <tr class="listrow[% loop.count % 2 %]">
+    <td>
+     [%- IF cfg.previous_id %]
+     <a href="amcvar.pl?action=swap_cvar_configs&module=[% HTML.url(module) %]&id1=[% HTML.url(cfg.previous_id) %]&id2=[% HTML.url(cfg.id) %]">
+      <img border="0" src="image/up.png"></a>
+     [%- END %]
+    </td>
+
+    <td>
+     [%- IF cfg.next_id %]
+     <a href="amcvar.pl?action=swap_cvar_configs&module=[% HTML.url(module) %]&id1=[% HTML.url(cfg.next_id) %]&id2=[% HTML.url(cfg.id) %]">
+      <img border="0" src="image/down.png"></a>
+     [%- END %]
+    </td>
+
+    <td>
+     <a href="amcvar.pl?action=edit_cvar_config&module=[% HTML.url(module) %]&id=[% HTML.url(cfg.id) %]&callback=[% HTML.url(callback) %]">
+      [% HTML.escape(cfg.name) %]
+     </a>
+    </td>
+
+    <td>[% HTML.escape(cfg.description) %]</td>
+    <td>[% HTML.escape(cfg.type_tr) %]</td>
+
+    <td>
+     [%- IF cfg.searchable %]
+     <translate>Yes</translate>
+     [%- ELSE %]
+     <translate>No</translate>
+     [%- END %]
+    </td>
+
+    <td>
+     [%- IF cfg.included_by_default %]
+     <translate>Yes, included by default</translate>
+     [%- ELSIF cfg.includeable %]
+     <translate>Yes</translate>
+     [%- ELSE %]
+     <translate>No</translate>
+     [%- END %]
+    </td>
+   </tr>
+   [%- END %]
+  </table>
+ </p>
+
+ <hr height="3">
+
+ <p>
+  <form method="post" action="amcvar.pl">
+   <input type="hidden" name="add_nextsub" value="add_cvar_config">
+   <input type="hidden" name="module" value="[% HTML.escape(module) %]">
+   <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+
+   <input type="submit" class="submit" name="action" value="<translate>Add</translate>">
+  </form>
+ </p>
+
+</body>
+</html>
diff --git a/templates/webpages/amcvar/render_inputs_de.html b/templates/webpages/amcvar/render_inputs_de.html
new file mode 100644 (file)
index 0000000..b570c64
--- /dev/null
@@ -0,0 +1,35 @@
+[% USE HTML %]
+
+[%- IF var.type == 'bool' %]
+<input type="checkbox" name="cvar_[% HTML.escape(var.name) %]" value="1"[% IF var.value %] checked[% END %]>
+
+[%- ELSIF var.type == 'textfield' %]
+<textarea name="cvar_[% HTML.escape(var.name) %]" cols="[% HTML.escape(var.width) %]" rows="[% HTML.escape(var.height) %]">[% HTML.escape(var.value) %]</textarea>
+
+[%- ELSIF var.type == 'date' %]
+<input name="cvar_[% HTML.escape(var.name) %]" size="12" value="[% HTML.escape(var.value) %]">
+<input type="button" name="cvar_[% HTML.escape(var.name) %]_button" id="cvar_[% HTML.escape(var.name) %]_trigger" value="?">
+
+<script type="text/javascript">
+ <!--
+     Calendar.setup({ inputField : "cvar_[% HTML.escape(var.name) %]",
+                      ifFormat   :"[% myconfig_jsc_dateformat %]",
+                      align      : "BR",
+                      button     : "cvar_[% HTML.escape(var.name) %]_trigger" });
+   -->
+</script>
+
+[%- ELSIF var.type == 'timestamp' %]
+<input name="cvar_[% HTML.escape(var.name) %]" value="[% HTML.escape(var.value) %]">
+
+[%- ELSIF var.type == 'select' %]
+
+<select name="cvar_[% HTML.escape(var.name) %]">
+ [%- FOREACH option = var.OPTIONS %]
+ <option[% IF option.value == var.value %] selected[% END %]>[% HTML.escape(option.value) %]</option>
+ [%- END %]
+</select>
+
+[%- ELSE %]
+<input name="cvar_[% HTML.escape(var.name) %]" value="[% HTML.escape(var.value) %]"[% IF var.maxlength %]maxlength="[% HTML.escape(var.maxlength) %]"[% END %]>
+[%- END %]
diff --git a/templates/webpages/amcvar/render_inputs_master.html b/templates/webpages/amcvar/render_inputs_master.html
new file mode 100644 (file)
index 0000000..b570c64
--- /dev/null
@@ -0,0 +1,35 @@
+[% USE HTML %]
+
+[%- IF var.type == 'bool' %]
+<input type="checkbox" name="cvar_[% HTML.escape(var.name) %]" value="1"[% IF var.value %] checked[% END %]>
+
+[%- ELSIF var.type == 'textfield' %]
+<textarea name="cvar_[% HTML.escape(var.name) %]" cols="[% HTML.escape(var.width) %]" rows="[% HTML.escape(var.height) %]">[% HTML.escape(var.value) %]</textarea>
+
+[%- ELSIF var.type == 'date' %]
+<input name="cvar_[% HTML.escape(var.name) %]" size="12" value="[% HTML.escape(var.value) %]">
+<input type="button" name="cvar_[% HTML.escape(var.name) %]_button" id="cvar_[% HTML.escape(var.name) %]_trigger" value="?">
+
+<script type="text/javascript">
+ <!--
+     Calendar.setup({ inputField : "cvar_[% HTML.escape(var.name) %]",
+                      ifFormat   :"[% myconfig_jsc_dateformat %]",
+                      align      : "BR",
+                      button     : "cvar_[% HTML.escape(var.name) %]_trigger" });
+   -->
+</script>
+
+[%- ELSIF var.type == 'timestamp' %]
+<input name="cvar_[% HTML.escape(var.name) %]" value="[% HTML.escape(var.value) %]">
+
+[%- ELSIF var.type == 'select' %]
+
+<select name="cvar_[% HTML.escape(var.name) %]">
+ [%- FOREACH option = var.OPTIONS %]
+ <option[% IF option.value == var.value %] selected[% END %]>[% HTML.escape(option.value) %]</option>
+ [%- END %]
+</select>
+
+[%- ELSE %]
+<input name="cvar_[% HTML.escape(var.name) %]" value="[% HTML.escape(var.value) %]"[% IF var.maxlength %]maxlength="[% HTML.escape(var.maxlength) %]"[% END %]>
+[%- END %]
diff --git a/templates/webpages/amcvar/search_filter_de.html b/templates/webpages/amcvar/search_filter_de.html
new file mode 100644 (file)
index 0000000..1107f4c
--- /dev/null
@@ -0,0 +1,63 @@
+[% USE HTML %]
+
+   [%- FOREACH var = variables %]
+   [%- IF var.searchable %]
+   <tr>
+    <td align="right" valign="top">[% HTML.escape(var.description) %]</td>
+    <td valign="top">
+
+     [%- IF var.type == 'bool' %]
+     <select name="cvar_[% HTML.escape(var.name) %]">
+      <option value="">---</option>
+      <option value="yes">Ja</option>
+      <option value="no">Nein</option>
+     </select>
+
+     [%- ELSIF var.type == 'date' %]
+     von
+     <input name="cvar_[% HTML.escape(var.name) %]_from" size="12">
+     <input type="button" name="cvar_[% HTML.escape(var.name) %]_from_button" id="cvar_[% HTML.escape(var.name) %]_from_trigger" value="?">
+     bis
+     <input name="cvar_[% HTML.escape(var.name) %]_to" size="12">
+     <input type="button" name="cvar_[% HTML.escape(var.name) %]_to_button" id="cvar_[% HTML.escape(var.name) %]_to_trigger" value="?">
+
+     <script type="text/javascript">
+      <!--
+          Calendar.setup({ inputField : "cvar_[% HTML.escape(var.name) %]_from",
+                           ifFormat   :"[% myconfig_jsc_dateformat %]",
+                           align      : "BR",
+                           button     : "cvar_[% HTML.escape(var.name) %]_from_trigger" });
+          Calendar.setup({ inputField : "cvar_[% HTML.escape(var.name) %]_to",
+                           ifFormat   :"[% myconfig_jsc_dateformat %]",
+                           align      : "BR",
+                           button     : "cvar_[% HTML.escape(var.name) %]_to_trigger" });
+        -->
+     </script>
+
+     [%- ELSIF var.type == 'number' %]
+     <select name="cvar_[% HTML.escape(var.name) %]_qtyop">
+      <option selected>==</option>
+      <option>=/=</option>
+      <option>&gt;</option>
+      <option>&gt;=</option>
+      <option>&lt;</option>
+      <option>&lt;=</option>
+     </select>
+     <input name="cvar_[% HTML.escape(var.name) %]"[% IF var.maxlength %]maxlength="[% HTML.escape(var.maxlength) %]"[% END %]>
+
+     [% ELSIF var.type == 'select' %]
+     <select name="cvar_[% HTML.escape(var.name) %]">
+      <option value="" selected>---</option>
+      [%- FOREACH option = var.OPTIONS %]
+      <option>[% HTML.escape(option.value) %]</option>
+      [%- END %]
+     </select>
+
+     [%- ELSE %]
+     <input name="cvar_[% HTML.escape(var.name) %]"[% IF var.maxlength %]maxlength="[% HTML.escape(var.maxlength) %]"[% END %]>
+
+     [%- END %]
+    </td>
+   </tr>
+   [%- END %]
+   [%- END %]
diff --git a/templates/webpages/amcvar/search_filter_master.html b/templates/webpages/amcvar/search_filter_master.html
new file mode 100644 (file)
index 0000000..cd3ac5b
--- /dev/null
@@ -0,0 +1,63 @@
+[% USE HTML %]
+
+   [%- FOREACH var = variables %]
+   [%- IF var.searchable %]
+   <tr>
+    <td align="right" valign="top">[% HTML.escape(var.description) %]</td>
+    <td valign="top">
+
+     [%- IF var.type == 'bool' %]
+     <select name="cvar_[% HTML.escape(var.name) %]">
+      <option value="">---</option>
+      <option value="yes"><translate>Yes</translate></option>
+      <option value="no"><translate>No</translate></option>
+     </select>
+
+     [%- ELSIF var.type == 'date' %]
+     <translate>from (time)</translate>
+     <input name="cvar_[% HTML.escape(var.name) %]_from" size="12">
+     <input type="button" name="cvar_[% HTML.escape(var.name) %]_from_button" id="cvar_[% HTML.escape(var.name) %]_from_trigger" value="?">
+     <translate>to (time)</translate>
+     <input name="cvar_[% HTML.escape(var.name) %]_to" size="12">
+     <input type="button" name="cvar_[% HTML.escape(var.name) %]_to_button" id="cvar_[% HTML.escape(var.name) %]_to_trigger" value="?">
+
+     <script type="text/javascript">
+      <!--
+          Calendar.setup({ inputField : "cvar_[% HTML.escape(var.name) %]_from",
+                           ifFormat   :"[% myconfig_jsc_dateformat %]",
+                           align      : "BR",
+                           button     : "cvar_[% HTML.escape(var.name) %]_from_trigger" });
+          Calendar.setup({ inputField : "cvar_[% HTML.escape(var.name) %]_to",
+                           ifFormat   :"[% myconfig_jsc_dateformat %]",
+                           align      : "BR",
+                           button     : "cvar_[% HTML.escape(var.name) %]_to_trigger" });
+        -->
+     </script>
+
+     [%- ELSIF var.type == 'number' %]
+     <select name="cvar_[% HTML.escape(var.name) %]_qtyop">
+      <option selected>==</option>
+      <option>=/=</option>
+      <option>&gt;</option>
+      <option>&gt;=</option>
+      <option>&lt;</option>
+      <option>&lt;=</option>
+     </select>
+     <input name="cvar_[% HTML.escape(var.name) %]"[% IF var.maxlength %]maxlength="[% HTML.escape(var.maxlength) %]"[% END %]>
+
+     [% ELSIF var.type == 'select' %]
+     <select name="cvar_[% HTML.escape(var.name) %]">
+      <option value="" selected>---</option>
+      [%- FOREACH option = var.OPTIONS %]
+      <option>[% HTML.escape(option.value) %]</option>
+      [%- END %]
+     </select>
+
+     [%- ELSE %]
+     <input name="cvar_[% HTML.escape(var.name) %]"[% IF var.maxlength %]maxlength="[% HTML.escape(var.maxlength) %]"[% END %]>
+
+     [%- END %]
+    </td>
+   </tr>
+   [%- END %]
+   [%- END %]
diff --git a/templates/webpages/amcvar/search_include_de.html b/templates/webpages/amcvar/search_include_de.html
new file mode 100644 (file)
index 0000000..4c16c51
--- /dev/null
@@ -0,0 +1,25 @@
+[% USE HTML %]
+
+   [%- SET start_new_row = '1' %]
+
+   [%- FOREACH var = variables %]
+   [%- IF var.includeable %]
+   [%- IF start_new_row %]
+   <tr>
+    [%- SET start_new_row = '0' %]
+    [%- END %]
+    <td>
+     <input type="checkbox"
+            name="[% HTML.escape(include_prefix) %]cvar_[% HTML.escape(var.name) %]"
+            id="[% HTML.escape(include_prefix) %]cvar_[% HTML.escape(var.name) %]"
+            value="[% HTML.escape(include_value) %]"
+            [% IF var.included_by_default %] checked[% END %]>
+     <label for="[% HTML.escape(include_prefix) %]cvar_[% HTML.escape(var.name) %]">[% HTML.escape(var.description) %]</label>
+    </td>
+
+    [%- UNLESS loop.count % 4 %][%- SET start_new_row = '1' %][%- END %]
+    [%- IF start_new_row || loop.last %]
+   </tr>
+   [%- END %]
+   [%- END %]
+   [%- END %]
diff --git a/templates/webpages/amcvar/search_include_master.html b/templates/webpages/amcvar/search_include_master.html
new file mode 100644 (file)
index 0000000..4c16c51
--- /dev/null
@@ -0,0 +1,25 @@
+[% USE HTML %]
+
+   [%- SET start_new_row = '1' %]
+
+   [%- FOREACH var = variables %]
+   [%- IF var.includeable %]
+   [%- IF start_new_row %]
+   <tr>
+    [%- SET start_new_row = '0' %]
+    [%- END %]
+    <td>
+     <input type="checkbox"
+            name="[% HTML.escape(include_prefix) %]cvar_[% HTML.escape(var.name) %]"
+            id="[% HTML.escape(include_prefix) %]cvar_[% HTML.escape(var.name) %]"
+            value="[% HTML.escape(include_value) %]"
+            [% IF var.included_by_default %] checked[% END %]>
+     <label for="[% HTML.escape(include_prefix) %]cvar_[% HTML.escape(var.name) %]">[% HTML.escape(var.description) %]</label>
+    </td>
+
+    [%- UNLESS loop.count % 4 %][%- SET start_new_row = '1' %][%- END %]
+    [%- IF start_new_row || loop.last %]
+   </tr>
+   [%- END %]
+   [%- END %]
+   [%- END %]
index 422787f..eb73366 100644 (file)
@@ -1,4 +1,4 @@
-<body onLoad="fokus()">
+[% USE HTML %]<body onLoad="fokus()">
 <table width=100%>
   <tr>
     <th class=listtop>[% title %]</th>
@@ -15,7 +15,9 @@
 <li><a href="#" rel="shipto">Lieferadresse</a></li>
 <li><a href="#" rel="contacts">Ansprechpartner</a></li>
 <li><a href="#" rel="deliveries">Lieferungen</a></li>
-
+[%- IF CUSTOM_VARIABLES.size %]
+<li><a href="#" rel="custom_variables">Benutzerdefinierte Variablen</a></li>
+[%- END %]
 </ul>
 
 <div class="tabcontentstyle">
   </table>
 <br style="clear: left" /></div>
 
+[%- IF CUSTOM_VARIABLES.size %]
+<div id="custom_variables" class="tabcontent">
+
+ <p>
+  <table>
+   [%- FOREACH var = CUSTOM_VARIABLES %]
+   <tr>
+    <td align="right" valign="top">[% HTML.escape(var.description) %]</td>
+    <td valign="top">[% var.HTML_CODE %]</td>
+   </tr>
+   [%- END %]
+  </table>
+ </p>
+
+ <br style="clear: left" />
+</div>
+[%- END %]
+
 </div>
 
 <script type="text/javascript"><!--
index 20d4552..b8b3b1f 100644 (file)
@@ -1,4 +1,4 @@
-<body onLoad="fokus()">
+[% USE HTML %]<body onLoad="fokus()">
 <table width=100%>
   <tr>
     <th class=listtop>[% title %]</th>
@@ -15,7 +15,9 @@
 <li><a href="#" rel="shipto"><translate>Shipping Address</translate></a></li>
 <li><a href="#" rel="contacts">Ansprechpartner</a></li>
 <li><a href="#" rel="deliveries"><translate>Lieferungen</translate></a></li>
-
+[%- IF CUSTOM_VARIABLES.size %]
+<li><a href="#" rel="custom_variables"><translate>Custom Variables</translate></a></li>
+[%- END %]
 </ul>
 
 <div class="tabcontentstyle">
   </table>
 <br style="clear: left" /></div>
 
+[%- IF CUSTOM_VARIABLES.size %]
+<div id="custom_variables" class="tabcontent">
+
+ <p>
+  <table>
+   [%- FOREACH var = CUSTOM_VARIABLES %]
+   <tr>
+    <td align="right" valign="top">[% HTML.escape(var.description) %]</td>
+    <td valign="top">[% var.HTML_CODE %]</td>
+   </tr>
+   [%- END %]
+  </table>
+ </p>
+
+ <br style="clear: left" />
+</div>
+[%- END %]
+
 </div>
 
 <script type="text/javascript"><!--
index 4dbda8b..fb09310 100644 (file)
@@ -38,6 +38,8 @@
    </tr>
    [% END %]
 
+   [% CUSTOM_VARIABLES_FILTER_CODE %]
+
    <tr>
     <td></td>
     <td>
         <label for="l_quonumber">[% IF IS_CUSTOMER %]Angebote[% ELSE %]Preisanfragen[% END %]</label>
        </td>
       </tr>
+
+      [% CUSTOM_VARIABLES_INCLUSION_CODE %]
+
      </table>
     </td>
    </tr>
index 50e38d9..25eff40 100644 (file)
@@ -38,6 +38,8 @@
    </tr>
    [% END %]
 
+   [% CUSTOM_VARIABLES_FILTER_CODE %]
+
    <tr>
     <td></td>
     <td>
         <label for="l_quonumber">[% IF IS_CUSTOMER %]<translate>Quotations</translate>[% ELSE %]<translate>RFQs</translate>[% END %]</label>
        </td>
       </tr>
+
+      [% CUSTOM_VARIABLES_INCLUSION_CODE %]
+
      </table>
     </td>
    </tr>