From 8688e71eb56abdd9641f07a47135bb02841607fb Mon Sep 17 00:00:00 2001
From: Moritz Bunkus
Date: Thu, 10 Jan 2008 17:14:51 +0000
Subject: [PATCH] =?utf8?q?Implementation=20des=20Features=20"Benutzerdefin?=
=?utf8?q?ierte=20Variablen=20f=C3=BCr=20Kunden-=20und=20Lieferantenstammd?=
=?utf8?q?aten".?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit
---
SL/CT.pm | 22 +
SL/CVar.pm | 543 ++++++++++++++++++
SL/IR.pm | 5 +
SL/IS.pm | 7 +
amcvar.pl | 1 +
bin/mozilla/amcvar.pl | 193 +++++++
bin/mozilla/ct.pl | 32 +-
bin/mozilla/io.pl | 13 +-
doc/dokumentenvorlagen-und-variablen.html | 19 +
locale/de/all | 34 ++
locale/de/amcvar | 174 ++++++
locale/de/ap | 1 +
locale/de/ar | 1 +
locale/de/cp | 2 +
locale/de/ct | 2 +
locale/de/dn | 2 +
locale/de/gl | 1 +
locale/de/ic | 2 +
locale/de/io | 2 +
locale/de/ir | 1 +
locale/de/is | 1 +
locale/de/licenses | 2 +
locale/de/menu | 4 +
locale/de/menunew | 4 +
menu.ini | 23 +
sql/Pg-upgrade2/custom_variables.sql | 51 ++
.../amcvar/display_cvar_config_form_de.html | 117 ++++
.../display_cvar_config_form_master.html | 132 +++++
.../webpages/amcvar/list_cvar_configs_de.html | 79 +++
.../amcvar/list_cvar_configs_master.html | 79 +++
.../webpages/amcvar/render_inputs_de.html | 35 ++
.../webpages/amcvar/render_inputs_master.html | 35 ++
.../webpages/amcvar/search_filter_de.html | 63 ++
.../webpages/amcvar/search_filter_master.html | 63 ++
.../webpages/amcvar/search_include_de.html | 25 +
.../amcvar/search_include_master.html | 25 +
templates/webpages/ct/form_header_de.html | 24 +-
templates/webpages/ct/form_header_master.html | 24 +-
templates/webpages/ct/search_de.html | 5 +
templates/webpages/ct/search_master.html | 5 +
40 files changed, 1846 insertions(+), 7 deletions(-)
create mode 100644 SL/CVar.pm
create mode 120000 amcvar.pl
create mode 100644 bin/mozilla/amcvar.pl
create mode 100644 locale/de/amcvar
create mode 100644 sql/Pg-upgrade2/custom_variables.sql
create mode 100644 templates/webpages/amcvar/display_cvar_config_form_de.html
create mode 100644 templates/webpages/amcvar/display_cvar_config_form_master.html
create mode 100644 templates/webpages/amcvar/list_cvar_configs_de.html
create mode 100644 templates/webpages/amcvar/list_cvar_configs_master.html
create mode 100644 templates/webpages/amcvar/render_inputs_de.html
create mode 100644 templates/webpages/amcvar/render_inputs_master.html
create mode 100644 templates/webpages/amcvar/search_filter_de.html
create mode 100644 templates/webpages/amcvar/search_filter_master.html
create mode 100644 templates/webpages/amcvar/search_include_de.html
create mode 100644 templates/webpages/amcvar/search_include_master.html
diff --git a/SL/CT.pm b/SL/CT.pm
index e5ee4af82..e0e4084d5 100644
--- a/SL/CT.pm
+++ b/SL/CT.pm
@@ -36,7 +36,10 @@
#======================================================================
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
index 000000000..80379582b
--- /dev/null
+++ b/SL/CVar.pm
@@ -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;
diff --git a/SL/IR.pm b/SL/IR.pm
index 6950739b0..8fa92e637 100644
--- 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();
diff --git a/SL/IS.pm b/SL/IS.pm
index 8ecddffde..367c8615f 100644
--- 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
index 000000000..385000d1b
--- /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
index 000000000..57457acc2
--- /dev/null
+++ b/bin/mozilla/amcvar.pl
@@ -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;
diff --git a/bin/mozilla/ct.pl b/bin/mozilla/ct.pl
index 673aa09c3..d4c5230d3 100644
--- a/bin/mozilla/ct.pl
+++ b/bin/mozilla/ct.pl
@@ -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');
diff --git a/bin/mozilla/io.pl b/bin/mozilla/io.pl
index 771e390f9..e331ff7c7 100644
--- a/bin/mozilla/io.pl
+++ b/bin/mozilla/io.pl
@@ -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;
diff --git a/doc/dokumentenvorlagen-und-variablen.html b/doc/dokumentenvorlagen-und-variablen.html
index b9ca939c4..c05b9b28c 100644
--- a/doc/dokumentenvorlagen-und-variablen.html
+++ b/doc/dokumentenvorlagen-und-variablen.html
@@ -81,6 +81,9 @@ td {
Variablen für die Zahlungseingänge
+
+
+ Benutzerdefinierte Kunden- und Lieferantenvariablen
@@ -817,6 +820,22 @@ td {
+
+
+
+ Die vom Benutzer definierten Variablen für Kunden und
+ Lieferanten stehen beim Ausdruck von Einkaufs- und Verkaufsbelegen
+ ebenfalls zur Verfügung. Ihre Namen setzen sich aus dem
+ Präfix vc_cvar_
und dem vom Benutzer festgelegten
+ Variablennamen zusammen.
+
+ Beispiel: Der Benutzer hat eine Variable
+ namens number_of_employees
definiert, die die Anzahl
+ der Mitarbeiter des Unternehmens enthält. Diese Variable steht
+ dann unter dem Namen vc_cvar_number_of_employees
zur
+ Verfügung.
+
zum Inhaltsverzeichnis
diff --git a/locale/de/all b/locale/de/all
index 91e5a5858..ff7bdbe37 100644
--- a/locale/de/all
+++ b/locale/de/all
@@ -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ügen und bearbeiten',
+ 'Add custom variable' => 'Benutzerdefinierte Variable erfassen',
'Add to group' => 'Zu Gruppe hinzufügen',
'Add unit' => 'Einheit hinzufü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äß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ü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ö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ü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ö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ä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ählen',
'Select the checkboxes that match users to the groups they should belong to.' => 'Wählen Sie diejenigen Checkboxen aus, die die Benutzer zu den gewü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ür die Auswahl verfügbaren Einträge enthalten. Die Einträge werden mit \'##\' voneinander getrennt. Beispiel: \'Früh##Normal##Spä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öhe des Textfeldes. Wenn nicht anders angegeben, so werden sie 30 Zeichen breit und fünf Zeichen hoch dargestellt.',
+ 'Text variables: \'MAXLENGTH=n\' sets the maximum entry length to \'n\'.' => 'Textzeilen: \'MAXLENGTH=n\' setzt eine Maximallä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 ü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 überprüfen Sie die Angaben in config/authentication.pl.',
'The authentication configuration file "config/authentication.pl" does not exist. This Lx-Office installation has probably not been updated correctly yet. Please contact your administrator.' => 'Die Konfigurationsdatei für die Authentifizierung "config/authentication.pl" wurde nicht gefunden. Diese Lx-Office-Installation wurde vermutlich noch nicht vollstä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ügbaren Optionen hängen vom Variablentypen ab:',
'The backup you upload here has to be a file created with "pg_dump -o -Ft".' => 'Die von Ihnen hochzuladende Sicherungsdatei muss mit dem Programm und den Parametern "pg_dump -o -Ft" 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ö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ö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ö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ö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ä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ä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 ("[% HTML.escape(memberfile) %]"). 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 ("[% HTML.escape(memberfile) %]"). 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ö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ü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äge in der Datenbank, fü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äßig an',
+ 'Yes/No (Checkbox)' => 'Ja/Nein (Checkbox)',
'You are logged out!' => 'Auf Wiedersehen!',
'You can also create new units now.' => 'Sie können jetzt auch neue Einheiten anlegen.',
'You can create a missing dataset by going back and chosing "Create Dataset".' => 'Sie können eine fehlende Datenbank erstellen, indem Sie jetzt zuück gehen und den Punkt "Datenbank anlegen" wählen.',
diff --git a/locale/de/amcvar b/locale/de/amcvar
new file mode 100644
index 000000000..07d51f1ab
--- /dev/null
+++ b/locale/de/amcvar
@@ -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ü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 überprüfen Sie die Angaben in config/authentication.pl.',
+ 'CANCELED' => 'Storniert',
+ 'Cc' => 'Cc',
+ 'Change Lx-Office installation settings (all menu entries beneath \'System\')' => 'Verändern der Lx-Office-Installationseinstellungen (Menü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äge erfassen und bearbeiten',
+ 'Create and edit sales delivery orders' => 'Lieferscheine für Kunden erfassen und bearbeiten',
+ 'Create and edit sales orders' => 'Auftragsbestä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ä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ü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ählen',
+ 'Select a vendor' => 'Einen Lieferanten auswä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 überprü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ü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üsselt werden (Fehler bei SSL/TLS-Initialisierung). Bitte überprü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ö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ä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ügen nicht ü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üsselwort "DB_config" fehlt.',
+ 'config/authentication.pl: Key "LDAP_config" is missing.' => 'config/authentication.pl: Der Schlü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ö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ö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;
diff --git a/locale/de/ap b/locale/de/ap
index 455c02fc6..c6877f3ef 100644
--- a/locale/de/ap
+++ b/locale/de/ap
@@ -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',
diff --git a/locale/de/ar b/locale/de/ar
index 6ed63b1f5..c4b7b963c 100644
--- a/locale/de/ar
+++ b/locale/de/ar
@@ -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',
diff --git a/locale/de/cp b/locale/de/cp
index 26567de28..0deefacec 100644
--- a/locale/de/cp
+++ b/locale/de/cp
@@ -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ügen nicht über die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
'Zero amount posting!' => 'Buchung ohne Wert',
'[email]' => '[email]',
diff --git a/locale/de/ct b/locale/de/ct
index a5873ce4d..bc7e0a12b 100644
--- a/locale/de/ct
+++ b/locale/de/ct
@@ -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ügen nicht über die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
'[email]' => '[email]',
'bin_list' => 'Lagerliste',
diff --git a/locale/de/dn b/locale/de/dn
index 74afbaaa7..2db8e023f 100644
--- a/locale/de/dn
+++ b/locale/de/dn
@@ -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ügen nicht über die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
'Zipcode' => 'PLZ',
'[email]' => '[email]',
diff --git a/locale/de/gl b/locale/de/gl
index 4a9c07f13..5ecf7a9f1 100644
--- a/locale/de/gl
+++ b/locale/de/gl
@@ -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',
diff --git a/locale/de/ic b/locale/de/ic
index 507a3ec51..15515f2d7 100644
--- a/locale/de/ic
+++ b/locale/de/ic
@@ -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ügen nicht über die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
'Zipcode' => 'PLZ',
'[email]' => '[email]',
diff --git a/locale/de/io b/locale/de/io
index 5e75bb402..15a587970 100644
--- a/locale/de/io
+++ b/locale/de/io
@@ -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ügen nicht über die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
'Zipcode' => 'PLZ',
'[email]' => '[email]',
diff --git a/locale/de/ir b/locale/de/ir
index c891565b9..c16bf5d97 100644
--- a/locale/de/ir
+++ b/locale/de/ir
@@ -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',
diff --git a/locale/de/is b/locale/de/is
index cdef5a507..2a286c8b6 100644
--- a/locale/de/is
+++ b/locale/de/is
@@ -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',
diff --git a/locale/de/licenses b/locale/de/licenses
index e61adfe2a..0bd5b00cf 100644
--- a/locale/de/licenses
+++ b/locale/de/licenses
@@ -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ügen nicht über die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
'Zipcode' => 'PLZ',
'[email]' => '[email]',
diff --git a/locale/de/menu b/locale/de/menu
index 6304d8674..fd59978b1 100644
--- a/locale/de/menu
+++ b/locale/de/menu
@@ -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ä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',
diff --git a/locale/de/menunew b/locale/de/menunew
index b8b71d92f..09c356648 100644
--- a/locale/de/menunew
+++ b/locale/de/menunew
@@ -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ä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',
diff --git a/menu.ini b/menu.ini
index fe28f11be..8f0d8d43c 100644
--- 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
index 000000000..884594a53
--- /dev/null
+++ b/sql/Pg-upgrade2/custom_variables.sql
@@ -0,0 +1,51 @@
+-- @tag: custom_variables
+-- @description: Benutzerdefinierte Variablen für beliebige Module. Hier nur fü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
index 000000000..0bee90ba6
--- /dev/null
+++ b/templates/webpages/amcvar/display_cvar_config_form_de.html
@@ -0,0 +1,117 @@
+[% USE HTML %]
+
+
+
+ [% title %]
+
+
+
+
+