use SL::DB::AuthUser;
use SL::DB::AuthGroup;
use SL::DB::Printer;
-use SL::DBUtils;
use SL::Helper::Flash;
use SL::Locale::String qw(t8);
use SL::System::InstallationLock;
use Rose::Object::MakeMethods::Generic
(
'scalar --get_set_init' => [ qw(client user group printer db_cfg is_locked
- all_dateformats all_numberformats all_countrycodes all_stylesheets all_menustyles all_clients all_groups all_users all_rights all_printers
+ all_dateformats all_numberformats all_countrycodes all_countrymodes all_stylesheets all_menustyles all_clients all_groups all_users all_rights all_printers
all_dbsources all_used_dbsources all_accounting_methods all_inventory_systems all_profit_determinations all_charts) ],
);
sub action_login {
my ($self) = @_;
-
return $self->login_form if !$::form->{do_login};
return if !$self->authenticate_root;
return if !$self->check_auth_db_and_tables;
sub action_new_user {
my ($self) = @_;
+ my $defaults = SL::DefaultManager->new($::lx_office_conf{system}->{default_manager});
$self->user(SL::DB::AuthUser->new(
config_values => {
vclimit => 200,
- countrycode => "de",
- numberformat => scalar(grep(/^Switzerland/, get_default_coa($self))) ? "1'000.00" : "1.000,00",
- dateformat => "dd.mm.yy",
+ countrycode => $defaults->language('de'),
+ numberformat => $defaults->numberformat('1.000,00'),
+ dateformat => $defaults->dateformat('dd.mm.yy'),
stylesheet => "kivitendo.css",
menustyle => "neu",
},
return [ map { id => $_, title => $cc{$_} }, sort { $cc{$a} cmp $cc{$b} } keys %cc ];
}
+sub init_all_countrymodes {
+ my %cm = SL::DefaultManager->country_modes;
+ return [ map { id => $_, title => "$_ ($cm{$_})" }, sort keys %cm ];
+}
+
#
# filters
#
sub setup_layout {
my ($self, $action) = @_;
+ my $defaults = SL::DefaultManager->new($::lx_office_conf{system}->{default_manager});
$::request->layout(SL::Layout::Dispatcher->new(style => 'admin'));
$::form->{favicon} = "favicon.ico";
%::myconfig = (
- countrycode => 'de',
- numberformat => '1.000,00',
- dateformat => 'dd.mm.yy',
+ countrycode => $defaults->language('de'),
+ numberformat => $defaults->numberformat('1.000,00'),
+ dateformat => $defaults->dateformat('dd.mm.yy'),
) if !%::myconfig;
}
sub create_dataset_form {
my ($self, %params) = @_;
+ my $defaults = SL::DefaultManager->new($::lx_office_conf{system}->{default_manager});
+
+ $::request->layout(SL::Layout::Dispatcher->new(style => 'admin'));
+ $::form->{favicon} = "favicon.ico";
+ $::form->{countrymode} = $defaults->country( 'DE' );
+ $::form->{chart} = $defaults->chart_of_accounts( 'Germany-DATEV-SKR03EU' );
+ $::form->{defaultcurrency} = $defaults->currency( 'EUR' );
+ $::form->{precision} = $defaults->precision( '0.01' );
+ $::form->{accounting_method} = $defaults->accounting_method( 'cash' );
+ $::form->{inventory_system} = $defaults->inventory_system( 'periodic' );
+ $::form->{profit_determination} = $defaults->profit_determination( 'balance' );
$self->render('admin/create_dataset', title => (t8('Database Administration') . " / " . t8('Create Dataset')));
}
return undef;
}
-sub get_default_coa {
- my ( $self ) = @_;
- my $coa = undef;
- eval {
- my $client = first { $_->is_default } @{ $self->all_clients };
- my $dbconnect = 'dbi:Pg:dbname=' . $client->dbname . ';host=' . $client->dbhost . ';port=' . $client->dbport;
- my $dbh = DBI->connect($dbconnect, $client->dbuser, $client->dbpasswd);
- my $query = q{ SELECT coa FROM defaults };
- ($coa) = selectrow_query($::form, $dbh, $query);
- $dbh->disconnect;
- };
- return $coa;
-}
-
1;
use SL::Locale::String qw(t8);
use SL::PriceSource::ALL;
use SL::Template;
-use SL::DBUtils;
__PACKAGE__->run_before('check_auth');
my ($self, %params) = @_;
$::form->{use_templates} = $self->defaults->templates ? 'existing' : 'new';
- $::form->{use_case} = scalar(grep(/^Switzerland/, (selectrow_query($::form, $::form->get_standard_dbh, 'SELECT coa FROM defaults'))[0]));
+ $::form->{country_mode} = $self->defaults->country_mode;
$self->edit_form;
}
customer_hourly_rate => { type => 'numeric', precision => 8, scale => 2 },
customer_projects_only_in_sales => { type => 'boolean', default => 'false', not_null => 1 },
customernumber => { type => 'text' },
+ country_mode => { type => 'text', default => 'DE', not_null => 1 },
datev_check_on_ap_transaction => { type => 'boolean', default => 'true' },
datev_check_on_ar_transaction => { type => 'boolean', default => 'true' },
datev_check_on_gl_transaction => { type => 'boolean', default => 'true' },
--- /dev/null
+package SL::DefaultManager;
+
+use strict;
+
+use SL::Util qw(camelify);
+use List::Util qw(first);
+
+my %manager_cache;
+
+sub new {
+ my ($class, @defaults) = @_;
+ bless [ @defaults ], $class;
+}
+
+sub _managers {
+ my ($self) = @_;
+
+ map { $self->_get($_) } @$self;
+}
+
+sub _get {
+ my ($class, $name) = @_;
+
+ return if !$name;
+
+ $manager_cache{$name} ||= do {
+ die "'$name' doesn't look like a default manager." unless $name =~ /^\w+$/a;
+
+ my $package = 'SL::DefaultManager::' . camelify($name);
+
+ eval "require $package; 1" or die "could not load default manager '$package': $@";
+
+ $package->new;
+ }
+}
+
+sub country_modes {
+ my ($self) = @_;
+ return (
+ 'CH' => 'Switzerland',
+ 'DE' => 'Germany',
+ )
+}
+
+sub AUTOLOAD {
+ our $AUTOLOAD;
+
+ my ($self, @args) = @_;
+
+ my $method = $AUTOLOAD;
+ $method =~ s/.*:://;
+ return if $method eq 'DESTROY';
+
+ my $manager = first { $_->can($method) } $self->_managers;
+
+ return $manager ? $manager->$method : @args;
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::DefaultManager - sets of defaults for use outside of clients
+
+=head1 SYNOPSIS
+
+ # during startup
+ my $defaults = SL::DefaultManager->new($::lx_office_conf{default_manager});
+
+ # during tests
+ my $defaults = SL::DefaultManager->new('swiss');
+
+ # in consuming code
+ # will return what the manager provides, or the given value if $defaults does
+ # not handle dateformat
+ my $dateformat = $defaults->dateformat('dd.mm.yyyy');
+
+ # have several default managers for different tasks
+ # if polled the first defined response will win
+ my $defaults = SL::DefaultManager->new('swiss', 'mobile', 'point_of_sale');
+
+=head1 DESCRIPTION
+
+TODO
+
+=head1 FUNCTIONS
+
+TODO
+
+=head1 BUGS
+
+None yet :)
+
+=head1 AUTHOR
+
+Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
+
+=cut
--- /dev/null
+package SL::DefaultManager::German;
+
+use strict;
+use parent qw(Rose::Object);
+
+# client defaults
+sub chart_of_accounts { 'Germany-DATEV-SKR03EU' }
+sub accounting_method { 'cash' }
+sub inventory_system { 'periodic' }
+sub profit_determination { 'income' }
+sub currency { 'EUR' }
+sub precision { 0.01 }
+
+# user defaults
+sub numberformat { '1.000,00' }
+sub dateformat { 'dd.mm.yy' }
+sub timeformat { 'hh:mm' }
+
+# default for login/admin areas
+sub country { 'DE' }
+sub language { 'de' }
+
+1;
--- /dev/null
+package SL::DefaultManager::Swiss;
+
+use strict;
+use parent qw(Rose::Object);
+
+# client defaults
+sub chart_of_accounts { 'Switzerland-deutsch-MWST-2014' }
+sub accounting_method { 'accrual' }
+sub inventory_system { 'periodic' }
+sub profit_determination { 'balance' }
+sub currency { 'CHF' }
+sub precision { 0.05 }
+
+# user defaults
+sub numberformat { "1'000.00" }
+sub dateformat { 'dd.mm.yy' }
+sub timeformat { 'hh:mm' }
+
+# default for login/admin areas
+sub country { 'CH' }
+sub language { 'de' }
+
+1;
sub round_amount {
my ($self, $amount, $places, $adjust) = @_;
+ return 0 if !defined $amount;
+
if ($adjust) {
- my $precision = 0.01;
+ my $precision = SL::DB::Default->get->precision || 0.01;
# Round amounts to eight places before rounding to the requested
# number of places. This gets rid of errors due to internal floating
# point representation.
$amount = int($amount * 10**8 + .5 * ($amount <=> 0)) / 10**8 if $places < 8;
- $amount = int($amount / ($precision = _get_precision()) + ($amount <=> 0) * .5) * $precision;
+ $amount = int($amount / $precision + ($amount <=> 0) * .5) * $precision;
$amount = int($amount * 10**$places + .5 * ($amount <=> 0)) / 10**$places;
return $amount;
}
- return 0 if !defined $amount;
-
# We use Perl's knowledge of string representation for
# rounding. First, convert the floating point number to a string
# with a high number of places. Then split the string on the decimal
return ($amount,$tax);
};
-sub _get_precision {
- my ( $self ) = @_;
- my $precision = 0.01;
- eval {
- my $client = $::auth->{client};
- my $dbconnect = 'dbi:Pg:dbname=' . $client->{dbname} . ';host=' . $client->{dbhost} . ';port=' . $client->{dbport};
- my $dbh = DBI->connect($dbconnect, $client->{dbuser}, $client->{dbpasswd});
- my $query = q{ SELECT precision FROM defaults };
- ($precision) = selectrow_query($::form, $dbh, $query);
- $dbh->disconnect;
- };
- return $precision;
-}
-
1;
__END__
(SELECT c.accno FROM chart c WHERE d.expense_accno_id = c.id) AS expense_accno,
(SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
(SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
- (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno,
- (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno
+ (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno,
+ (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno
${query_transdate}
FROM defaults d|;
use SL::Menu;
use SL::Presenter;
-use SL::DBUtils;
my %menu_cache;
}
sub init_menu {
- my @menu_files;
- my $dbh = $::form->get_standard_dbh;
- if(scalar(grep(/^Switzerland/, (selectrow_query($::form, $dbh, 'SELECT coa FROM defaults'))[0]))) {
- @menu_files = qw(menus/erp_ch.ini);
- } else {
- @menu_files = qw(menus/erp.ini);
- }
- $dbh->commit;
- unshift @menu_files, 'menus/crm.ini' if $::instance_conf->crm_installed;
- Menu->new(@menu_files);
+ SL::Menu->new('user');
}
sub init_auto_reload_resources_param {
use SL::Common;
use SL::Iconv;
use SL::Inifile;
+use XML::LibXML;
use strict;
-my %locales_by_country;
+my %locales_by_language;
sub new {
$main::lxdebug->enter_sub();
- my ($type, $country) = @_;
+ my ($type, $language) = @_;
- $country ||= $::lx_office_conf{system}->{language};
- $country =~ s|.*/||;
- $country =~ s|\.||g;
+ $language ||= $::lx_office_conf{system}->{language};
+ $language =~ s|.*/||;
+ $language =~ s|\.||g;
- if (!$locales_by_country{$country}) {
+ if (!$locales_by_language{$language}) {
my $self = {};
bless $self, $type;
- $self->_init($country);
+ $self->_init($language);
- $locales_by_country{$country} = $self;
+ $locales_by_language{$language} = $self;
}
$main::lxdebug->leave_sub();
- return $locales_by_country{$country}
+ return $locales_by_language{$language}
}
sub _init {
my $self = shift;
- my $country = shift;
+ my $language = shift;
- $self->{countrycode} = $country;
+ $self->{countrycode} = $language;
- if ($country && -d "locale/$country") {
- if (open my $in, "<", "locale/$country/all") {
- local $/ = undef;
- my $code = <$in>;
+ if ($language && -d "locale/$language") {
+ local *IN;
+ if (open(IN, "<", "locale/$language/all")) {
+ my $code = join("", <IN>);
eval($code);
- close($in);
+ close(IN);
}
- if (-d "locale/$country/more") {
- opendir my $dh, "locale/$country/more" or die "can't open locale/$country/more: $!";
- my @files = sort grep -f "locale/$country/more/$_", readdir $dh;
+ if (-d "locale/$language/more") {
+ opendir my $dh, "locale/$language/more" or die "can't open locale/$language/more: $!";
+ my @files = sort grep -f "locale/$language/more/$_", readdir $dh;
close $dh;
for my $file (@files) {
- if (open my $in, "<", "locale/$country/more/$file") {
+ if (open my $in, "<", "locale/$language/more/$file") {
local $/ = undef;
my $code = <$in>;
eval($code);
$self->{iconv_to_iso8859} = SL::Iconv->new('UTF-8', 'ISO-8859-15');
$self->{iconv_utf8} = SL::Iconv->new('UTF-8', 'UTF-8');
- $self->_read_special_chars_file($country);
+ $self->_read_special_chars_file($language);
push @{ $self->{LONG_MONTH} },
("January", "February", "March", "April",
sub _read_special_chars_file {
my $self = shift;
- my $country = shift;
+ my $language = shift;
- if (! -f "locale/$country/special_chars") {
+ if (! -f "locale/$language/special_chars") {
$self->{special_chars_map} = {};
return;
}
- $self->{special_chars_map} = Inifile->new("locale/$country/special_chars", 'verbatim' => 1);
+ $self->{special_chars_map} = Inifile->new("locale/$language/special_chars", 'verbatim' => 1);
foreach my $format (keys %{ $self->{special_chars_map} }) {
next if (($format eq 'FILE') || ($format eq 'ORDER') || (ref $self->{special_chars_map}->{$format} ne 'HASH'));
return $::instance_conf->data->{$setting};
}
-sub parse_compare_string {
- my ($self, $switch) = @_;
- my ($setting, $mode) = split m/=/, $switch, 2;
- return $::instance_conf->data->{$setting} eq $mode;
-}
-
sub clear_access {
my ($self) = @_;
for my $node ($self->tree_walk("all")) {
sub set_access {
my ($self) = @_;
- # 1. evaluate appearence
- # 2. evaluate access for all
- # 3. if a menu has no visible children, its not visible either
+ # 1. evaluate access for all
+ # 2. if a menu has no visible children, its not visible either
for my $node (reverse $self->tree_walk("all")) {
- $node->{visible} = $node->{inclusion} ? $self->parse_compare_string($node->{inclusion}) : 1
- && $node->{exclusion} ? !$self->parse_compare_string($node->{exclusion}) : 1
- && $node->{access} ? $self->parse_access_string($node)
+ $node->{visible} = $node->{access} ? $self->parse_access_string($node)
: !$node->{children} ? 1
: $node->{visible_children} ? 1
: 0;
(SELECT c.accno FROM chart c WHERE d.expense_accno_id = c.id) AS expense_accno,
(SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
(SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
- (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno,
- (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno
+ (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno,
+ (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno
$query_add
FROM defaults d|;
my $ref = selectfirst_hashref_query($form, $dbh, $query);
use SL::Iconv;
use SL::Inifile;
use SL::System::InstallationLock;
+use SL::DefaultManager;
use strict;
$dbupdater->process_query($dbh, "sql/lx-office.sql");
# process update-scripts needed before 1st user-login
- $dbupdater->process_query($dbh, "sql/Pg-upgrade2/defaults_add_precision.sql");
$self->create_schema_info_table($form, $dbh);
+ $dbupdater->process_query($dbh, "sql/Pg-upgrade2/defaults_add_precision.sql");
$dbh->do("INSERT INTO schema_info (tag, login) VALUES ('defaults_add_precision', 'admin')");
+ $dbupdater->process_query($dbh, "sql/Pg-upgrade2/defaults_add_country_mode.sql");
+ $dbh->do("INSERT INTO schema_info (tag, login) VALUES ('defaults_add_country_mode', 'admin')");
# load chart of accounts
$dbupdater->process_query($dbh, "sql/$form->{chart}-chart.sql");
- $query = qq|UPDATE defaults SET coa = ?, accounting_method = ?, profit_determination = ?, inventory_system = ?, curr = ?, precision = ?|;
- do_query($form, $dbh, $query, map { $form->{$_} } qw(chart accounting_method profit_determination inventory_system defaultcurrency precision));
+ $query = qq|UPDATE defaults SET coa = ?, accounting_method = ?, profit_determination = ?, inventory_system = ?, curr = ?, precision = ?, country_mode = ?|;
+ do_query($form, $dbh, $query, map { $form->{$_} } qw(chart accounting_method profit_determination inventory_system defaultcurrency precision countrymode));
$dbh->disconnect;
sub get_default_myconfig {
my ($self_or_class, %user_config) = @_;
+ my $defaults = SL::DefaultManager->new($::lx_office_conf{system}->{default_manager});
return (
- countrycode => 'de',
+ countrycode => $defaults->language('de'),
css_path => 'css', # Needed for menunew, see SL::Layout::Base::get_stylesheet_for_user
- dateformat => 'dd.mm.yy',
- numberformat => '1.000,00',
+ dateformat => $defaults->dateformat('dd.mm.yy'),
+ numberformat => $defaults->numberformat('1.000,00'),
stylesheet => 'kivitendo.css',
- timeformat => 'hh:mm',
+ timeformat => $defaults->timeformat('hh:mm'),
%user_config,
);
}
my $select_eur = q|<option value=""> |. $locale->text('None') .q|</option>\n|;
my %eur;
- if ($form->{use_case} = scalar(grep(/^Switzerland/, (selectrow_query($form, $form->get_standard_dbh, 'SELECT coa FROM defaults'))[0]))) {
+ if (($form->{country_mode} = SL::DB::Default->get->country_mode) eq 'CH') {
%eur = (
1 => "Ertrag",
6 => "Aufwand",
# and "en" (English, not perfect) are available.
language = de
+# Set default_manager for admin forms. Currently "german"
+# and "swiss" are available.
+default_manager = german
+
[paths]
# path to temporary files (must be writeable by the web server)
userspath = users
+++ /dev/null
-[Master Data]
-
-[Master Data--Add Customer]
-ACCESS=customer_vendor_edit
-module=controller.pl
-action=CustomerVendor/add
-db=customer
-
-[Master Data--Add Vendor]
-ACCESS=customer_vendor_edit
-module=controller.pl
-action=CustomerVendor/add
-db=vendor
-
-[Master Data--Add Part]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=add
-item=part
-
-[Master Data--Add Service]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=add
-item=service
-
-[Master Data--Add Assembly]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=add
-item=assembly
-
-[Master Data--Add Project]
-ACCESS=project_edit
-module=controller.pl
-action=Project/new
-
-[Master Data--Update Prices]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=search_update_prices
-
-
-[Master Data--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Master Data--Reports--Customers]
-ACCESS=customer_vendor_edit
-module=controller.pl
-action=CustomerVendor/search
-db=customer
-
-[Master Data--Reports--Vendors]
-ACCESS=customer_vendor_edit
-module=controller.pl
-action=CustomerVendor/search
-db=vendor
-
-[Master Data--Reports--Contacts]
-ACCESS=customer_vendor_edit
-module=controller.pl
-action=CustomerVendor/search_contact
-db=customer
-
-[Master Data--Reports--Parts]
-ACCESS=part_service_assembly_details
-module=ic.pl
-action=search
-searchitems=part
-
-[Master Data--Reports--Services]
-ACCESS=part_service_assembly_details
-module=ic.pl
-action=search
-searchitems=service
-
-[Master Data--Reports--Assemblies]
-ACCESS=part_service_assembly_details
-module=ic.pl
-action=search
-searchitems=assembly
-
-[Master Data--Reports--Projects]
-ACCESS=project_edit
-module=controller.pl
-action=Project/search
-
-[AR]
-
-[AR--Add Quotation]
-ACCESS=sales_quotation_edit
-module=oe.pl
-action=add
-type=sales_quotation
-
-[AR--Add Sales Order]
-ACCESS=sales_order_edit
-module=oe.pl
-action=add
-type=sales_order
-
-[AR--Add Delivery Order]
-ACCESS=sales_delivery_order_edit
-module=do.pl
-action=add
-type=sales_delivery_order
-
-[AR--Add Sales Invoice]
-ACCESS=invoice_edit
-module=is.pl
-action=add
-type=invoice
-
-[AR--Add Credit Note]
-ACCESS=invoice_edit
-module=is.pl
-action=add
-type=credit_note
-
-[AR--Add Dunning]
-ACCESS=dunning_edit
-module=dn.pl
-action=add
-
-[AR--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[AR--Reports--Quotations]
-ACCESS=sales_quotation_edit
-module=oe.pl
-action=search
-type=sales_quotation
-
-[AR--Reports--Sales Orders]
-ACCESS=sales_order_edit
-module=oe.pl
-action=search
-type=sales_order
-
-[AR--Reports--Delivery Orders]
-ACCESS=sales_delivery_order_edit
-module=do.pl
-action=search
-type=sales_delivery_order
-
-[AR--Reports--Invoices, Credit Notes & AR Transactions]
-ACCESS=invoice_edit
-module=ar.pl
-action=search
-nextsub=ar_transactions
-
-[AR--Reports--Sales Report]
-ACCESS=invoice_edit
-module=vk.pl
-action=search_invoice
-nextsub=invoice_transactions
-
-[AR--Reports--Dunnings]
-ACCESS=dunning_edit
-module=dn.pl
-action=search
-
-[AR--Reports--Delivery Plan]
-ACCESS=sales_order_edit
-module=controller.pl
-action=DeliveryPlan/list
-
-[AP]
-
-[AP--Add RFQ]
-ACCESS=request_quotation_edit
-module=oe.pl
-action=add
-type=request_quotation
-
-[AP--Add Purchase Order]
-ACCESS=purchase_order_edit
-module=oe.pl
-action=add
-type=purchase_order
-
-[AP--Add Delivery Note]
-ACCESS=purchase_delivery_order_edit
-module=do.pl
-action=add
-type=purchase_delivery_order
-
-[AP--Add Vendor Invoice]
-ACCESS=vendor_invoice_edit
-module=ir.pl
-action=add
-type=invoice
-
-
-[AP--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[AP--Reports--RFQs]
-ACCESS=request_quotation_edit
-module=oe.pl
-action=search
-type=request_quotation
-
-[AP--Reports--Purchase Orders]
-ACCESS=purchase_order_edit
-module=oe.pl
-action=search
-type=purchase_order
-
-[AP--Reports--Delivery Orders]
-ACCESS=purchase_delivery_order_edit
-module=do.pl
-action=search
-type=purchase_delivery_order
-
-[AP--Reports--Vendor Invoices & AP Transactions]
-ACCESS=vendor_invoice_edit
-module=ap.pl
-action=search
-nextsub=ap_transactions
-
-
-[Warehouse]
-
-[Warehouse--Stock]
-ACCESS=warehouse_management
-module=controller.pl
-action=Inventory/stock_in
-
-[Warehouse--Produce Assembly]
-ACCESS=warehouse_management
-module=wh.pl
-action=transfer_warehouse_selection
-trans_type=assembly
-
-[Warehouse--Transfer]
-ACCESS=warehouse_management
-module=wh.pl
-action=transfer_warehouse_selection
-trans_type=transfer
-
-[Warehouse--Removal]
-ACCESS=warehouse_management
-module=wh.pl
-action=transfer_warehouse_selection
-trans_type=removal
-
-[Warehouse--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Warehouse--Reports--Warehouse content]
-ACCESS=warehouse_contents | warehouse_management
-module=wh.pl
-action=report
-
-[Warehouse--Reports--WHJournal]
-ACCESS=warehouse_management
-module=wh.pl
-action=journal
-
-
-[General Ledger]
-
-[General Ledger--Add Transaction]
-ACCESS=general_ledger
-module=gl.pl
-action=add
-
-[General Ledger--Add AR Transaction]
-ACCESS=general_ledger
-module=ar.pl
-action=add
-
-[General Ledger--Add AP Transaction]
-ACCESS=general_ledger
-module=ap.pl
-action=add
-
-
-[General Ledger--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-
-[General Ledger--Reports--AR Aging]
-ACCESS=general_ledger
-module=rp.pl
-action=report
-report=ar_aging
-
-
-[General Ledger--Reports--AP Aging]
-ACCESS=general_ledger
-module=rp.pl
-action=report
-report=ap_aging
-
-[General Ledger--Reports--Journal]
-ACCESS=general_ledger
-module=gl.pl
-action=search
-
-
-[Cash]
-ACCESS=cash
-
-[Cash--Receipt]
-module=cp.pl
-action=payment
-type=receipt
-vc=customer
-
-[Cash--Payment]
-module=cp.pl
-action=payment
-type=check
-vc=vendor
-
-[Cash--Reconciliation]
-ACCESS=cash
-module=rc.pl
-action=reconciliation
-
-[Cash--Bank collection via SEPA]
-module=sepa.pl
-action=bank_transfer_add
-vc=customer
-
-[Cash--Bank transfer via SEPA]
-module=sepa.pl
-action=bank_transfer_add
-vc=vendor
-
-[Cash--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Cash--Reports--Receipts]
-module=rp.pl
-action=report
-report=receipts
-
-[Cash--Reports--Payments]
-module=rp.pl
-action=report
-report=payments
-
-[Cash--Reports--Bank collections via SEPA]
-module=sepa.pl
-action=bank_transfer_search
-vc=customer
-
-[Cash--Reports--Bank transfers via SEPA]
-module=sepa.pl
-action=bank_transfer_search
-vc=vendor
-
-[Reports]
-
-[Reports--Chart of Accounts]
-ACCESS=report
-module=ca.pl
-action=chart_of_accounts
-
-[Reports--Trial Balance]
-ACCESS=report
-module=rp.pl
-action=report
-report=trial_balance
-
-[Reports--Erfolgsrechnung]
-ACCESS=report
-module=rp.pl
-action=report
-report=erfolgsrechnung
-
-[Reports--Projecttransactions]
-ACCESS=report
-module=rp.pl
-action=report
-report=projects
-
-
-[Batch Printing]
-ACCESS=batch_printing
-
-[Batch Printing--Sales Invoices]
-ACCESS=invoice_edit
-module=bp.pl
-action=search
-vc=customer
-type=invoice
-
-[Batch Printing--Sales Orders]
-ACCESS=sales_order_edit
-module=bp.pl
-action=search
-vc=customer
-type=sales_order
-
-[Batch Printing--Quotations]
-ACCESS=sales_quotation_edit
-module=bp.pl
-action=search
-vc=customer
-type=sales_quotation
-
-[Batch Printing--Packing Lists]
-ACCESS=invoice_edit | sales_order_edit
-module=bp.pl
-action=search
-vc=customer
-type=packing_list
-
-[Batch Printing--Purchase Orders]
-ACCESS=purchase_order_edit
-module=bp.pl
-action=search
-vc=vendor
-type=purchase_order
-
-[Batch Printing--RFQs]
-ACCESS=request_quotation_edit
-module=bp.pl
-action=search
-vc=vendor
-type=request_quotation
-
-[Batch Printing--Checks]
-ACCESS=cash
-module=bp.pl
-action=search
-vc=vendor
-type=check
-
-[Batch Printing--Receipts]
-ACCESS=cash
-module=bp.pl
-action=search
-vc=customer
-type=receipt
-
-
-[Productivity]
-ACCESS=productivity
-
-[Productivity--Show TODO list]
-module=todo.pl
-action=show_todo_list
-
-[Productivity--Add Follow-Up]
-module=fu.pl
-action=add
-
-[Productivity--Edit Access Rights]
-module=fu.pl
-action=edit_access_rights
-
-[Productivity--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Productivity--Reports--Follow-Ups]
-module=fu.pl
-action=search
-
-
-[System]
-ACCESS=config
-
-[System--Client Configuration]
-ACCESS=admin
-module=controller.pl
-action=ClientConfig/edit
-
-[System--Edit Dunning]
-module=dn.pl
-action=edit_config
-
-[System--Chart of Accounts]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Chart of Accounts--Add Account]
-module=am.pl
-action=add_account
-
-[System--Chart of Accounts--List Accounts]
-module=am.pl
-action=list_account
-
-[System--Buchungsgruppen]
-module=am.pl
-action=list_buchungsgruppe
-
-[System--Taxes]
-module=am.pl
-action=list_tax
-
-[System--Bank accounts]
-module=bankaccounts.pl
-action=bank_account_list
-
-[System--Groups]
-module=pe.pl
-action=search
-type=partsgroup
-
-[System--Pricegroups]
-module=pe.pl
-action=search
-type=pricegroup
-
-[System--Edit units]
-module=am.pl
-action=edit_units
-
-[System--Price Factors]
-module=am.pl
-action=list_price_factors
-
-[System--Departments]
-module=controller.pl
-action=Department/list
-
-[System--Types of Business]
-module=controller.pl
-action=Business/list
-
-[System--Leads]
-module=am.pl
-action=list_lead
-
-[System--Languages and translations]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Languages and translations--Add Language]
-module=am.pl
-action=add_language
-
-[System--Languages and translations--List Languages]
-module=am.pl
-action=list_language
-
-[System--Languages and translations--Greetings]
-module=generictranslations.pl
-action=edit_greetings
-
-[System--Languages and translations--SEPA strings]
-module=generictranslations.pl
-action=edit_sepa_strings
-
-
-[System--Payment Terms]
-module=controller.pl
-action=PaymentTerm/list
-
-[System--Manage Custom Variables]
-module=controller.pl
-action=CustomVariableConfig/list
-
-[System--Warehouses]
-module=am.pl
-action=list_warehouses
-
-
-[System--Import CSV]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Import CSV--Customers and vendors]
-module=controller.pl
-action=CsvImport/new
-profile.type=customers_vendors
-
-[System--Import CSV--Contacts]
-module=controller.pl
-action=CsvImport/new
-profile.type=contacts
-
-[System--Import CSV--Shipto]
-module=controller.pl
-action=CsvImport/new
-profile.type=addresses
-
-[System--Import CSV--Parts]
-module=controller.pl
-action=CsvImport/new
-profile.type=parts
-
-[System--Import CSV--Projects]
-module=controller.pl
-action=CsvImport/new
-profile.type=projects
-
-[System--Templates]
-ACCESS=admin
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Templates--HTML Templates]
-module=amtemplates.pl
-action=display_template_form
-type=templates
-format=html
-
-[System--Templates--LaTeX Templates]
-module=amtemplates.pl
-action=display_template_form
-type=templates
-format=tex
-
-[System--Templates--Stylesheet]
-module=amtemplates.pl
-action=display_template_form
-type=stylesheet
-
-[System--General Ledger Corrections]
-module=acctranscorrections.pl
-action=analyze_filter
-
-[System--Background jobs and task server]
-ACCESS=admin
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Background jobs and task server--List current background jobs]
-module=controller.pl
-action=BackgroundJob/list
-
-[System--Background jobs and task server--Background job history]
-module=controller.pl
-action=BackgroundJobHistory/list
-
-[System--Background jobs and task server--Task server control]
-module=controller.pl
-action=TaskServer/show
-
-[System--Audit Control]
-module=am.pl
-action=audit_control
-
-[System--History Search Engine]
-module=am.pl
-action=show_history_search
-
-[System--Employees]
-ACCESS=admin
-module=controller.pl
-action=Employee/list
-
-[Program]
-
-[Program--User Preferences]
-module=am.pl
-action=config
-
-[Program--Version]
-module=login.pl
-action=company_logo
-no_todo_list=1
-
-[Program--Administration area]
-ACCESS=display_admin_link
-module=controller.pl
-action=Admin/login
-
-[Program--Documentation (in German)]
-href=doc/kivitendo-Dokumentation.pdf
-target=_blank
-
-[Program--kivitendo website (external)]
-href=http://www.kivitendo.de/
-target=_blank
-
-[Program--Logout]
-module=controller.pl
-action=LoginScreen/logout
id: general_ledger_datev_export_assistent
name: DATEV - Export Assistent
icon: datev
- exclusion: country_mode=CH
order: 400
access: datev_export
module: datev.pl
params:
action: report
report: trial_balance
-- parent: reports
- id: reports_erfolgsrechnung
- name: Erfolgsrechnung
- icon: income_statement
- order: 300
- inclusion: country_mode=CH
- access: report
- module: rp.pl
- params:
- action: report
- report: erfolgsrechnung
- parent: reports
id: reports_income_statement
name: Income Statement
icon: income_statement
order: 300
- exclusion: country_mode=CH
access: report
module: rp.pl
params:
id: reports_bwa
name: BWA
order: 400
- exclusion: country_mode=CH
access: report
module: rp.pl
params:
name: Balance Sheet
icon: balance_sheet
order: 500
- exclusion: country_mode=CH
access: report
module: rp.pl
params:
name: UStVa
icon: ustva
order: 600
- exclusion: country_mode=CH
access: advance_turnover_tax_return
module: ustva.pl
params:
id: system_ustva_einstellungen
name: UStVa Einstellungen
order: 200
- exclusion: country_mode=CH
module: ustva.pl
params:
action: config_step1
+++ /dev/null
-bin/mozilla/am.pl
-SL/AM.pm
-SL/Form.pm
-SL/BackgroundJob/CreatePeriodicInvoices.pm
-SL/BackgroundJob/SelfTest.pm
-SL/DBUpgrade2.pm
-SL/Controller/LoginScreen.pm
-SL/Controller/Admin.pm
}
}
-if (@missing_modules && $apt && !$check{s}) {
+if (@missing_modules && ($check{a} || $apt && !$check{s})) {
print "\nHere are some sample installation lines, choose one appropriate for your system:\n\n";
local $Text::Wrap::separator = " \\\n";
sub print_line {
my ($text, $res, $color) = @_;
- return if $check{s};
+ return if $check{s} && !$check{a};
print $text, " ", ('.' x (78 - length($text) - length($res))), " ", mycolor($res, $color), $/;
}
sub print_header {
- return if $check{s};
+ return if $check{s} && !$check{a};
print $/;
print "$_[0]:", $/;
}
--- /dev/null
+-- @tag: defaults_add_country_mode
+-- @description: adds new column 'country_mode' (ISO-3166) in table defaults used for erp.ini
+-- @depends: release_3_2_0
+ALTER TABLE defaults ADD COLUMN country_mode TEXT NOT NULL DEFAULT('DE');
+
use SL::LXDebug;
use SL::Layout::None;
use SL::LxOfficeConf;
+use XML::LibXML;
our ($db_cfg, $dbh);
$dbh = SL::DBConnect->connect(@dbi_options) || BAIL_OUT("Database connection failed: " . $DBI::errstr);
$::auth->{dbh} = $dbh;
my $dbupdater = SL::DBUpgrade2->new(form => $::form, return_on_error => 1, silent => 1);
- my $coa = 'Germany-DATEV-SKR03EU';
+ my $defaults = SL::DefaultManager->new($::lx_office_conf{system}->{default_manager});
+ my $coa = $defaults->chart_of_accounts( 'Germany-DATEV-SKR03EU' );
+ my $am = $defaults->accounting_method( 'cash' );
+ my $pd = $defaults->profit_determination( 'balance' );
+ my $is = $defaults->inventory_system( 'periodic' );
+ my $curr = $defaults->currency( 'EUR' );
apply_dbupgrade($dbupdater, "sql/lx-office.sql");
apply_dbupgrade($dbupdater, "sql/${coa}-chart.sql");
- dbh_do($dbh, qq|UPDATE defaults SET coa = '${coa}', accounting_method = 'cash', profit_determination = 'income', inventory_system = 'periodic', curr = 'EUR'|);
+ dbh_do($dbh, qq|UPDATE defaults SET coa = '${coa}', accounting_method = '${am}', profit_determination = '${pd}', inventory_system = '${is}', curr = '${curr}'|);
dbh_do($dbh, qq|CREATE TABLE schema_info (tag TEXT, login TEXT, itime TIMESTAMP DEFAULT now(), PRIMARY KEY (tag))|);
}
</tr>
<tr>
- <th valign="top" align="right" nowrap>[% LxERP.t8('Create Chart of Accounts') %]</th>
- <td>[% L.select_tag('chart', SELF.all_charts, onchange='comment_selected_chart(this.value)', default=(FORM.chart || 'Germany-DATEV-SKR03EU')) %]</td>
+ <th valign="top" align="right" nowrap>[% LxERP.t8('Country') %]</th>
+ <td>[% L.select_tag('countrymode', SELF.all_countrymodes, title_key="title", default=(FORM.countrymode), onchange='select_country_defaults(this.value)') %]</td>
+ </tr>
+
+ <tr>
+ <td colspan="1"> </td>
+ <td><hr size="1" noshade></td>
</tr>
<tr>
<th align="right" nowrap>[% LxERP.t8('Default currency') %]</th>
- <td>[% L.input_tag('defaultcurrency', FORM.defaultcurrency || 'EUR') %]</td>
+ <td>[% L.input_tag('defaultcurrency', FORM.defaultcurrency) %]</td>
</tr>
<tr>
<th align="right" nowrap>[% LxERP.t8('Precision') %]</th>
- <td>[% L.input_tag('precision', FORM.precision || '0.01') %]</td>
+ <td>[% L.input_tag('precision', FORM.precision) %]</td>
+ </tr>
+
+ <tr>
+ <th valign="top" align="right" nowrap>[% LxERP.t8('Create Chart of Accounts') %]</th>
+ <td>[% L.select_tag('chart', SELF.all_charts, default=(FORM.chart), onchange='comment_selected_chart(this.value)') %]</td>
</tr>
<tr>
<th valign="top" align="right" nowrap>[% LxERP.t8('Accounting method') %]</th>
- <td>[% L.select_tag('accounting_method', SELF.all_accounting_methods, title_key='name', default=(FORM.accounting_method || 'cash')) %]</td>
+ <td>[% L.select_tag('accounting_method', SELF.all_accounting_methods, title_key='name', default=(FORM.accounting_method)) %]</td>
</tr>
<tr>
<th valign="top" align="right" nowrap>[% LxERP.t8('Inventory system') %]</th>
- <td>[% L.select_tag('inventory_system', SELF.all_inventory_systems, title_key='name', default=(FORM.inventory_system || 'periodic')) %]</td>
+ <td>[% L.select_tag('inventory_system', SELF.all_inventory_systems, title_key='name', default=(FORM.inventory_system)) %]</td>
</tr>
<tr>
<th valign="top" align="right" nowrap>[% LxERP.t8('Profit determination') %]</th>
- <td>[% L.select_tag('profit_determination', SELF.all_profit_determinations, title_key='name', default=(FORM.profit_determination || 'income')) %]</td>
+ <td>[% L.select_tag('profit_determination', SELF.all_profit_determinations, title_key='name', default=(FORM.profit_determination)) %]</td>
</tr>
</table>
"fuer Kunden im Ausland." +
"\n" +
"Hinweis vom 20.09.2011");
- } else if (/^Switzerland/.test(s)) {
+ }
+ return true;
+}
+
+function select_country_defaults(country) {
+ if (/^CH/.test(country)) {
document.getElementById('defaultcurrency').value='CHF';
document.getElementById('precision').value='0.05';
+ document.getElementById('chart').value='Switzerland-deutsch-MWST-2014';
document.getElementById('accounting_method').value='accrual';
document.getElementById('inventory_system').value='periodic';
document.getElementById('profit_determination').value='balance';
} else {
- document.getElementById("defaultcurrency").value="EUR";
+ document.getElementById('defaultcurrency').value='EUR';
document.getElementById('precision').value='0.01';
+ document.getElementById('chart').value='Germany-DATEV-SKR03EU';
document.getElementById('accounting_method').value='cash';
document.getElementById('inventory_system').value='periodic';
document.getElementById('profit_determination').value='income';
<input type="hidden" name="expense_accno_id" value="[% HTML.escape(expense_accno_id) %]">
<input type="hidden" name="fxgain_accno_id" value="[% HTML.escape(fxgain_accno_id) %]">
<input type="hidden" name="fxloss_accno_id" value="[% HTML.escape(fxloss_accno_id) %]">
-<input type="hidden" name="rndgain_accno_id" value="[% HTML.escape(rndgain_accno_id) %]">
-<input type="hidden" name="rndloss_accno_id" value="[% HTML.escape(rndloss_accno_id) %]">
+<input type="hidden" name="rndgain_accno_id" value="[% HTML.escape(rndgain_accno_id) %]">
+<input type="hidden" name="rndloss_accno_id" value="[% HTML.escape(rndloss_accno_id) %]">
<fieldset>
<legend>
<tr>
<th align="left">[% 'Taxkey' | $T8 %]</th>
<th align="left">[% 'valid from' | $T8 %]</th>
- <th align="left">[% 'pos_ustva' | $T8 %]</th>
+ [% IF country_mode != 'CH' %]
+ <th align="left">[% 'pos_ustva' | $T8 %]</th>
+ [% END %]
<th align="left">[% 'delete' | $T8 %] ? </th>
</tr>
[% FOREACH tk = ACCOUNT_TAXKEYS %]
<input type="hidden" name="taxkey_id_[% tk.runningnumber %]" value="[% tk.id %]">
<td><select name="taxkey_tax_[% tk.runningnumber %]">[% tk.selecttaxkey %]</select></td>
<td><input name="taxkey_startdate_[% tk.runningnumber %]" value="[% HTML.escape(tk.startdate) %]"></td>
- <td><select name="taxkey_pos_ustva_[% tk.runningnumber %]">[% tk.select_tax %]</select></td>
+ [% IF country_mode != 'CH' %]
+ <td><select name="taxkey_pos_ustva_[% tk.runningnumber %]">[% tk.select_tax %]</select></td>
+ [% END %]
<td><input name="taxkey_del_[% tk.runningnumber %]" type="checkbox"
class="checkbox" value="delete"></td>
[% ELSE %]
<input type="hidden" name="taxkey_id_[% tk.runningnumber %]" value="NEW">
<td><select name="taxkey_tax_[% tk.runningnumber %]">[% tk.selecttaxkey %]</select></td>
<td><input name="taxkey_startdate_[% tk.runningnumber %]" value="[% HTML.escape(tk.startdate) %]"></td>
- <td><select name="taxkey_pos_ustva_[% tk.runningnumber %]">[% tk.select_tax %]</select></td>
+ [% IF country_mode != 'CH' %]
+ <td><select name="taxkey_pos_ustva_[% tk.runningnumber %]">[% tk.select_tax %]</select></td>
+ [% END %]
<td> </td>
[% END %]
</tr>
<th align="left">[% 'EUER' | $T8 %]</th>
<td colspan="3"><select name="pos_eur">[% select_eur %]</select></td>
</tr>
- [% IF use_case == 0 %]
+ [% IF country_mode != 'CH' %]
<tr>
<th align="left">[% 'BWA' | $T8 %]</th>
<td colspan="3"><select name="pos_bwa">[% select_bwa %]</select></td>
<tr>
<td align="right">[% LxERP.t8("Rounding Gain") %]</td>
- <td>[% L.select_tag('defaults.rndgain_accno_id', SELF.defaults.rndgain_accno_id, category='I,A', choose=1, style=style) %]</td>
+ <td>[% L.chart_picker('defaults.rndgain_accno_id', SELF.defaults.rndgain_accno_id, category='I,A', choose=1, style=style) %]</td>
</tr>
<tr>
<td align="right">[% LxERP.t8("Rounding Loss") %]</td>
- <td>[% L.select_tag('defaults.rndloss_accno_id', SELF.accounts.rndloss_accno_id, category='E,A', choose=1, style=style) %]</td>
+ <td>[% L.chart_picker('defaults.rndloss_accno_id', SELF.defaults.rndloss_accno_id, category='E,A', choose=1, style=style) %]</td>
</tr>
<tr>
<li><a href="#ranges_of_numbers">[% LxERP.t8('Ranges of numbers') %]</a></li>
<li><a href="#default_accounts">[% LxERP.t8('Default Accounts') %]</a></li>
<li><a href="#posting_configuration">[% LxERP.t8('Posting Configuration') %]</a></li>
- [% IF use_case == 0 %]
+ [% IF FORM.country_mode != 'CH' %]
<li><a href="#datev_check_configuration">[% LxERP.t8('DATEV check configuration') %]</a></li>
[% END %]
<li><a href="#orders_deleteable">[% LxERP.t8('Orders / Delivery Orders deleteable') %]</a></li>