return $self->{api_token} && $provided_api_token && ($self->{api_token} eq $provided_api_token);
}
-sub session_tables_present {
- my $self = shift;
+sub _tables_present {
+ my ($self, @tables) = @_;
+ my $cache_key = join '_', @tables;
# Only re-check for the presence of auth tables if either the check
# hasn't been done before of if they weren't present.
- if ($self->{session_tables_present}) {
- return $self->{session_tables_present};
- }
+ return $self->{"$cache_key\_tables_present"} ||= do {
+ my $dbh = $self->dbconnect(1);
- my $dbh = $self->dbconnect(1);
+ if (!$dbh) {
+ return 0;
+ }
- if (!$dbh) {
- return 0;
- }
+ my $query =
+ qq|SELECT COUNT(*)
+ FROM pg_tables
+ WHERE (schemaname = 'auth')
+ AND (tablename IN (@{[ join ', ', ('?') x @tables ]}))|;
- my $query =
- qq|SELECT COUNT(*)
- FROM pg_tables
- WHERE (schemaname = 'auth')
- AND (tablename IN ('session', 'session_content'))|;
+ my ($count) = selectrow_query($main::form, $dbh, $query, @tables);
- my ($count) = selectrow_query($main::form, $dbh, $query);
+ return scalar @tables == $count;
+ }
+}
- $self->{session_tables_present} = 2 == $count;
+sub session_tables_present {
+ $_[0]->_tables_present('session', 'session_content');
+}
- return $self->{session_tables_present};
+sub master_rights_present {
+ $_[0]->_tables_present('master_rights');
}
# --------------------------------------
sub all_rights_full {
- my $locale = $main::locale;
-
- my @all_rights = (
- ["--master_data", $locale->text("Master Data")],
- ["customer_vendor_edit", $locale->text("Create customers and vendors. Edit all vendors. Edit only customers where salesman equals employee (login)")],
- ["customer_vendor_all_edit", $locale->text("Create customers and vendors. Edit all vendors. Edit all customers")],
- ["part_service_assembly_edit", $locale->text("Create and edit parts, services, assemblies")],
- ["part_service_assembly_details", $locale->text("Show details and reports of parts, services, assemblies")],
- ["project_edit", $locale->text("Create and edit projects")],
- ["--ar", $locale->text("AR")],
- ["requirement_spec_edit", $locale->text("Create and edit requirement specs")],
- ["sales_quotation_edit", $locale->text("Create and edit sales quotations")],
- ["sales_order_edit", $locale->text("Create and edit sales orders")],
- ["sales_delivery_order_edit", $locale->text("Create and edit sales delivery orders")],
- ["invoice_edit", $locale->text("Create and edit invoices and credit notes")],
- ["dunning_edit", $locale->text("Create and edit dunnings")],
- ["sales_letter_edit", $locale->text("Edit sales letters")],
- ["sales_all_edit", $locale->text("View/edit all employees sales documents")],
- ["edit_prices", $locale->text("Edit prices and discount (if not used, textfield is ONLY set readonly)")],
- ["show_ar_transactions", $locale->text("Show AR transactions as part of AR invoice report")],
- ["delivery_plan", $locale->text("Show delivery plan")],
- ["delivery_value_report", $locale->text("Show delivery value report")],
- ["sales_letter_report", $locale->text("Show sales letters report")],
- ["--ap", $locale->text("AP")],
- ["request_quotation_edit", $locale->text("Create and edit RFQs")],
- ["purchase_order_edit", $locale->text("Create and edit purchase orders")],
- ["purchase_delivery_order_edit", $locale->text("Create and edit purchase delivery orders")],
- ["vendor_invoice_edit", $locale->text("Create and edit vendor invoices")],
- ["show_ap_transactions", $locale->text("Show AP transactions as part of AP invoice report")],
- ["--warehouse_management", $locale->text("Warehouse management")],
- ["warehouse_contents", $locale->text("View warehouse content")],
- ["warehouse_management", $locale->text("Warehouse management")],
- ["--general_ledger_cash", $locale->text("General ledger and cash")],
- ["general_ledger", $locale->text("Transactions, AR transactions, AP transactions")],
- ["datev_export", $locale->text("DATEV Export")],
- ["cash", $locale->text("Receipt, payment, reconciliation")],
- ["bank_transaction", $locale->text("Bank transactions")],
- ["--reports", $locale->text('Reports')],
- ["report", $locale->text('All reports')],
- ["advance_turnover_tax_return", $locale->text('Advance turnover tax return')],
- ["--batch_printing", $locale->text("Batch Printing")],
- ["batch_printing", $locale->text("Batch Printing")],
- ["--configuration", $locale->text("Configuration")],
- ["config", $locale->text("Change kivitendo installation settings (most entries in the 'System' menu)")],
- ["admin", $locale->text("Client administration: configuration, editing templates, task server control, background jobs (remaining entries in the 'System' menu)")],
- ["--others", $locale->text("Others")],
- ["email_bcc", $locale->text("May set the BCC field when sending emails")],
- ["productivity", $locale->text("Productivity")],
- ["display_admin_link", $locale->text("Show administration link")],
- );
-
- return @all_rights;
+ my ($self) = @_;
+
+ @{ $self->{master_rights} ||= do {
+ $self->dbconnect->selectall_arrayref("SELECT name, description, category FROM auth.master_rights ORDER BY id");
+ }
+ }
}
sub all_rights {
- return grep !/^--/, map { $_->[0] } all_rights_full();
+ return map { $_->[0] } grep { !$_->[2] } $_[0]->all_rights_full;
}
sub read_groups {
$group->{rights}->{$row->{right}} |= $row->{granted};
}
- map { $group->{rights}->{$_} = 0 if (!defined $group->{rights}->{$_}); } all_rights();
+ map { $group->{rights}->{$_} = 0 if (!defined $group->{rights}->{$_}); } $self->all_rights;
}
$sth->finish();
my $dbh = $self->dbconnect;
my ($query, $sth, $row, $rights);
- $rights = { map { $_ => 0 } all_rights() };
+ $rights = { map { $_ => 0 } $self->all_rights };
return $rights if !$self->client || !$login;
$::auth->set_session_value('admin_password', $::lx_office_conf{authentication}->{admin_password});
$::auth->create_or_refresh_session;
+ return if $self->apply_dbupgrade_scripts;
+
my $group = (SL::DB::Manager::AuthGroup->get_all(limit => 1))[0];
if (!$group) {
SL::DB::AuthGroup->new(
name => t8('Full Access'),
description => t8('Full access to all functions'),
- rights => [ map { SL::DB::AuthGroupRight->new(right => $_, granted => 1) } SL::Auth::all_rights() ],
+ rights => [ map { SL::DB::AuthGroupRight->new(right => $_, granted => 1) } $::auth->all_rights ],
)->save;
}
- if (!$self->apply_dbupgrade_scripts) {
- $self->action_login;
- }
+ $self->action_login;
}
#
my (@sections, $current_section);
foreach my $entry ($::auth->all_rights_full) {
- if ($entry->[0] =~ m/^--/) {
- push @sections, { description => $entry->[1], rights => [] };
+ if ($entry->[2]) {
+ push @sections, { description => t8($entry->[1]), rights => [] };
} elsif (@sections) {
push @{ $sections[-1]->{rights} }, {
name => $entry->[0],
- description => $entry->[1],
+ description => t8($entry->[1]),
};
} else {
sub action_empty {
my ($self) = @_;
- if ($::form->{format} eq 'json') {
+ if ($::form->{format} eq 'json' || $::request->type eq 'json') {
my $layout = {
pre_content => $::request->{layout}->pre_content,
start_content => $::request->{layout}->start_content,
};
$self->render(\ SL::JSON::to_json($layout), { type => 'json', process => 0 });
+ } else {
+ $self->render(\'', { process => 0 });
}
}
# Auth DB needs update? If so log the user out forcefully.
if (User::LOGIN_AUTH_DBUPDATE_AVAILABLE() == $result) {
$::auth->destroy_session;
- return $self->render('login_screen/auth_db_needs_update');
+ # must be without layout because menu rights might not exist yet
+ return $self->render('login_screen/auth_db_needs_update', { layout => 0 });
}
# Basic client tables available? If not tell the user to create them
push @elements, $bb;
}
- if ($::form->round_amount($bt_sum + $bb_sum) != 0) {
+ if ($::form->round_amount($bt_sum + $bb_sum, 2) != 0) {
push @errors, t8('Out of balance!');
}
if (@_) {
my %new_rights = ref($_[0]) eq 'HASH' ? %{ $_[0] } : @_;
- $self->rights([ map { SL::DB::AuthGroupRight->new(right => $_, granted => $new_rights{$_} ? 1 : 0) } SL::Auth::all_rights() ]);
+ $self->rights([ map { SL::DB::AuthGroupRight->new(right => $_, granted => $new_rights{$_} ? 1 : 0) } $::auth->all_rights ]);
}
return {
- map({ ($_ => 0) } SL::Auth::all_rights()),
+ map({ ($_ => 0) } $::auth->all_rights),
map({ ($_->right => $_->granted) } @{ $self->rights || [] })
};
}
goto &bool_value if $type eq 'bool';
goto ×tamp_value if $type eq 'timestamp';
- goto &number_value if $type eq 'number';
+
+ if ($type eq 'number') {
+ return defined($self->number_value) ? $self->number_value * 1 : undef;
+ }
if ( $type eq 'customer' ) {
require SL::DB::Customer;
sub items { goto &orderitems; }
sub add_items { goto &add_orderitems; }
sub payment_terms { goto &payment; }
+sub record_number { goto &donumber; }
sub sales_order {
my $self = shift;
return shift->customer_id ? 'sales_delivery_order' : 'purchase_delivery_order';
}
+sub displayable_type {
+ my $type = shift->type;
+
+ return $::locale->text('Sales Delivery Order') if $type eq 'sales_delivery_order';
+ return $::locale->text('Purchase Delivery Order') if $type eq 'purchase_delivery_order';
+
+ die 'invalid type';
+}
+
+sub displayable_name {
+ join ' ', grep $_, map $_[0]->$_, qw(displayable_type record_number);
+};
+
sub displayable_state {
my ($self) = @_;
use SL::DB::MetaSetup::DeliveryOrderItem;
use SL::DB::Helper::ActsAsList;
+use SL::DB::Helper::LinkedRecords;
use SL::DB::Helper::CustomVariables (
sub_module => 'delivery_order_items',
cvars_alias => 1,
# methods
+sub record { goto &delivery_order }
+
1;
sub items { goto &invoiceitems; }
sub add_items { goto &add_invoiceitems; }
+sub record_number { goto &invnumber; };
sub is_sales {
# For compatibility with Order, DeliveryOrder
return t8('Invoice');
}
+sub displayable_name {
+ join ' ', grep $_, map $_[0]->$_, qw(displayable_type record_number);
+};
+
sub abbreviation {
my ($self) = @_;
use SL::DB::MetaSetup::InvoiceItem;
use SL::DB::Helper::ActsAsList;
+use SL::DB::Helper::LinkedRecords;
use SL::DB::Helper::CustomVariables (
sub_module => 'invoice',
cvars_alias => 1,
__PACKAGE__->meta->initialize;
+sub record {
+ my ($self) = @_;
+
+ return $self->invoice if $self->invoice;
+ return $self->purchase_invoice if $self->purchase_invoice;
+ return;
+};
+
1;
sub items { goto &orderitems; }
sub add_items { goto &add_orderitems; }
+sub record_number { goto &number; }
sub type {
my $self = shift;
die 'invalid type';
}
+sub displayable_name {
+ join ' ', grep $_, map $_[0]->$_, qw(displayable_type record_number);
+};
sub is_sales {
croak 'not an accessor' if @_ > 1;
use SL::DB::Manager::OrderItem;
use SL::DB::DeliveryOrderItemsStock;
use SL::DB::Helper::ActsAsList;
+use SL::DB::Helper::LinkedRecords;
use SL::DB::Helper::CustomVariables (
sub_module => 'orderitems',
cvars_alias => 1,
return SL::DB::Manager::Order->find_by(id => $self->trans_id)->taxincluded ? $::locale->text('WARN: Tax included value!') : '';
}
+
+sub record { goto &order }
+
1;
$params{path_suffix} ||= '';
$params{schema} ||= '';
- $params{path} = "sql/Pg-upgrade2" . $params{path_suffix};
+ $params{path} ||= "sql/Pg-upgrade2" . $params{path_suffix};
map { $self->{$_} = $params{$_} } keys %params;
}
sub parse_dbupdate_controls {
- $::lxdebug->enter_sub();
-
my ($self) = @_;
my $form = $self->{form};
my $control = {
"priority" => 1000,
"depends" => [],
+ "locales" => [],
};
while (<IN>) {
if ($fields[0] eq "depends") {
push(@{$control->{"depends"}}, split(/\s+/, $fields[1]));
+ } elsif ($fields[0] eq "locales") {
+ push @{$control->{locales}}, $fields[1];
} else {
$control->{$fields[0]} = $fields[1];
}
$self->{all_controls} = \%all_controls;
- $::lxdebug->leave_sub();
-
return $self;
}
}
sub _dbupdate2_calculate_depth {
- $::lxdebug->enter_sub(2);
-
my ($tree, $tag) = @_;
my $node = $tree->{$tag};
- return $::lxdebug->leave_sub(2) if (defined($node->{"depth"}));
+ return if (defined($node->{"depth"}));
my $max_depth = 0;
}
$node->{"depth"} = $max_depth + 1;
-
- $::lxdebug->leave_sub(2);
}
sub sort_dbupdate_controls {
UPDATE delivery_order_items SET
delivery_order_id = ?, position = ?, parts_id = ?, description = ?, longdescription = ?, qty = ?, base_qty = ?,
sellprice = ?, discount = ?, unit = ?, reqdate = ?, project_id = ?, serialnumber = ?,
- ordnumber = ?, transdate = ?, cusordnumber = ?,
lastcost = ? , price_factor_id = ?, price_factor = (SELECT factor FROM price_factors where id = ?),
marge_price_factor = ?, pricegroup_id = ?, active_price_source = ?, active_discount_source = ?
WHERE id = ?
$form->{"sellprice_$i"}, $form->{"discount_$i"} / 100,
$form->{"unit_$i"}, conv_date($items_reqdate), conv_i($form->{"project_id_$i"}),
$form->{"serialnumber_$i"},
- $form->{"ordnumber_$i"}, conv_date($form->{"transdate_$i"}),
- $form->{"cusordnumber_$i"},
$form->{"lastcost_$i"},
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
conv_i($form->{"marge_price_factor_$i"}),
$::form->footer;
+ if ($self->_interface_is_fcgi) {
+ # fcgi? send send reponse on its way before cleanup.
+ $self->{request}->Flush;
+ $self->{request}->Finish;
+ }
+
+ $::lxdebug->end_request;
+
# cleanup
$::auth->save_session;
$::auth->expire_sessions;
$::request = undef;
Form::disconnect_standard_dbh;
- $::lxdebug->end_request;
-
$self->_watch_for_changed_files;
$::lxdebug->leave_sub;
jquery.multiselect2side
ui-lightness/jquery-ui
jquery-ui.custom
+ tooltipster themes/tooltipster-light
);
$layout->use_javascript("$_.js") for (qw(
jquery jquery-ui jquery.cookie jquery.checkall jquery.download
jquery/jquery.form jquery/fixes client_js
+ jquery/jquery.tooltipster.min
common part_selection switchmenuframe
), "jquery/ui/i18n/jquery.ui.datepicker-$::myconfig{countrycode}");
print $::request->{layout}->post_content;
if (my @inline_scripts = $::request->{layout}->javascripts_inline) {
- print "<script type='text/javascript'>@inline_scripts</script>\n";
+ print "<script type='text/javascript'>" . join("; ", @inline_scripts) . "</script>\n";
}
print <<EOL
use List::Util qw(max);
+use Carp;
use SL::AM;
use SL::ARAP;
use SL::CVar;
sub invoice_details {
$main::lxdebug->enter_sub();
+ # prepare invoice for printing
+
my ($self, $myconfig, $form, $locale) = @_;
$form->{duedate} ||= $form->{invdate};
if ($form->{"id_$i"} != 0) {
+ # Prepare linked items for printing
+ if ( $form->{"invoice_id_$i"} ) {
+
+ require SL::DB::InvoiceItem;
+ my $invoice_item = SL::DB::Manager::InvoiceItem->find_by( id => $form->{"invoice_id_$i"} );
+ my $linkeditems = $invoice_item->linked_records( direction => 'from', recursive => 1 );
+
+ # check for (recursively) linked sales quotation items, sales order
+ # items and sales delivery order items.
+
+ # The checks for $form->{"ordnumber_$i"} and quo and do are for the old
+ # behaviour, where this data was stored in its own database fields in
+ # the invoice items, and there were no record links for the items.
+
+ # If this information were to be fetched in retrieve_invoice, e.g. for showing
+ # this information in the second row, then these fields will already have
+ # been set and won't be calculated again. This shouldn't be done there
+ # though, as each invocation creates several database calls per item, and would
+ # make the interface very slow for many items. So currently these
+ # requests are only made when printing the record.
+
+ # When using the workflow an invoice item can only be (recursively) linked to at
+ # most one sales quotation item and at most one delivery order item. But it may
+ # be linked back to several order items, if collective orders were involved. If
+ # that is the case we will always choose the very first order item from the
+ # original order, i.e. where it first appeared in an order.
+
+ # TODO: credit note items aren't checked for a record link to their
+ # invoice item
+
+ unless ( $form->{"ordnumber_$i"} ) {
+
+ # $form->{"ordnumber_$i"} comes from ordnumber in invoice, if an
+ # entry exists this must be from before the change from ordnumber to linked items.
+ # So we just use that value and don't check for linked items.
+ # In that case there won't be any links for quo or do items either
+
+ # sales order items are fetched and sorted by id, the lowest id is first
+ # It is assumed that the id always grows, so the item we want (the original) will have the lowest id
+ # better solution: filter the order_item that doesn't have any links from other order_items
+ # or maybe fetch linked_records with param save_path and order by _record_length_depth
+ my @linked_orderitems = grep { $_->isa("SL::DB::OrderItem") && $_->record->type eq 'sales_order' } @{$linkeditems};
+ if ( scalar @linked_orderitems ) {
+ @linked_orderitems = sort { $a->id <=> $b->id } @linked_orderitems;
+ my $orderitem = $linked_orderitems[0]; # 0: the original order item, -1: the last collective order item
+
+ $form->{"ordnumber_$i"} = $orderitem->record->record_number;
+ $form->{"transdate_oe_$i"} = $orderitem->record->transdate->to_kivitendo;
+ $form->{"cusordnumber_oe_$i"} = $orderitem->record->cusordnumber;
+ };
+
+ my @linked_quoitems = grep { $_->isa("SL::DB::OrderItem") && $_->record->type eq 'sales_quotation' } @{$linkeditems};
+ if ( scalar @linked_quoitems ) {
+ croak "an invoice item may only be linked back to 1 sales quotation item, something is wrong\n" unless scalar @linked_quoitems == 1;
+ $form->{"quonumber_$i"} = $linked_quoitems[0]->record->record_number;
+ $form->{"transdate_quo_$i"} = $linked_quoitems[0]->record->transdate->to_kivitendo;
+ };
+
+ my @linked_deliveryorderitems = grep { $_->isa("SL::DB::DeliveryOrderItem") && $_->record->type eq 'sales_delivery_order' } @{$linkeditems};
+ if ( scalar @linked_deliveryorderitems ) {
+ croak "an invoice item may only be linked back to 1 sales delivery item, something is wrong\n" unless scalar @linked_deliveryorderitems == 1;
+ $form->{"donumber_$i"} = $linked_deliveryorderitems[0]->record->record_number;
+ $form->{"transdate_do_$i"} = $linked_deliveryorderitems[0]->record->transdate->to_kivitendo;
+ };
+ };
+ };
+
+
# add number, description and qty to $form->{number},
if ($form->{"subtotal_$i"} && !$subtotal_header) {
$subtotal_header = $i;
push @{ $form->{TEMPLATE_ARRAYS}->{deliverydate_oe} }, $form->{"reqdate_$i"};
push @{ $form->{TEMPLATE_ARRAYS}->{sellprice} }, $form->{"sellprice_$i"};
push @{ $form->{TEMPLATE_ARRAYS}->{sellprice_nofmt} }, $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+ # linked item print variables
+ push @{ $form->{TEMPLATE_ARRAYS}->{quonumber_quo} }, $form->{"quonumber_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{transdate_quo} }, $form->{"transdate_quo_$i"};
push @{ $form->{TEMPLATE_ARRAYS}->{ordnumber_oe} }, $form->{"ordnumber_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{transdate_oe} }, $form->{"transdate_oe_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{cusordnumber_oe} }, $form->{"cusordnumber_oe_$i"};
push @{ $form->{TEMPLATE_ARRAYS}->{donumber_do} }, $form->{"donumber_$i"};
- push @{ $form->{TEMPLATE_ARRAYS}->{transdate_oe} }, $form->{"transdate_$i"};
+ push @{ $form->{TEMPLATE_ARRAYS}->{transdate_do} }, $form->{"transdate_do_$i"};
+
push @{ $form->{TEMPLATE_ARRAYS}->{invnumber} }, $form->{"invnumber"};
push @{ $form->{TEMPLATE_ARRAYS}->{invdate} }, $form->{"invdate"};
push @{ $form->{TEMPLATE_ARRAYS}->{price_factor} }, $price_factor->{formatted_factor};
UPDATE invoice SET trans_id = ?, position = ?, parts_id = ?, description = ?, longdescription = ?, qty = ?,
sellprice = ?, fxsellprice = ?, discount = ?, allocated = ?, assemblyitem = ?,
unit = ?, deliverydate = ?, project_id = ?, serialnumber = ?, pricegroup_id = ?,
- ordnumber = ?, donumber = ?, transdate = ?, cusordnumber = ?, base_qty = ?, subtotal = ?,
+ base_qty = ?, subtotal = ?,
marge_percent = ?, marge_total = ?, lastcost = ?, active_price_source = ?, active_discount_source = ?,
price_factor_id = ?, price_factor = (SELECT factor FROM price_factors WHERE id = ?), marge_price_factor = ?
WHERE id = ?
$form->{"discount_$i"}, $allocated, 'f',
$form->{"unit_$i"}, conv_date($form->{"reqdate_$i"}), conv_i($form->{"project_id_$i"}),
$form->{"serialnumber_$i"}, $pricegroup_id,
- $form->{"ordnumber_$i"}, $form->{"donumber_$i"}, conv_date($form->{"transdate_$i"}),
- $form->{"cusordnumber_$i"}, $baseqty, $form->{"subtotal_$i"} ? 't' : 'f',
+ $baseqty, $form->{"subtotal_$i"} ? 't' : 'f',
$form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"},
$form->{"lastcost_$i"},
$form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"},
my ($type, $file, %options) = @_;
my $id = "";
- my $skip;
+ my $cur;
- local *FH;
+ my $self = { FILE => $file, ORDER => [] };
- my $self = { "FILE" => $file };
+ open my $fh, "$file" or $::form->error("$file : $!");
- open FH, "$file" or $::form->error("$file : $!");
-
- while (<FH>) {
+ for (<$fh>) {
chomp;
if (!$options{verbatim}) {
# strip comments
- s/\#.*//;
-
# remove any trailing whitespace
+ s/\s*#.*$//;
s/^\s*//;
- s/\s*$//;
} else {
- next if (m/^\s*\#/);
+ next if m/#/;
}
next unless $_;
- if (m/^\[/) {
- s/(\[|\])//g;
-
- $id = $_;
-
- $self->{$id} ||= { };
+ if (m/^\[(.*)\]$/) {
+ $id = $1;
+ $cur = $self->{$1} ||= { };
- push @{ $self->{ORDER} }, $_;
-
- next;
+ push @{ $self->{ORDER} }, $1;
+ } else {
+ # add key=value to $id
+ my ($key, $value) = split m/=/, $_, 2;
+ $cur->{$key} = $value;
}
- # add key=value to $id
- my ($key, $value) = split m/=/, $_, 2;
-
- $self->{$id}->{$key} = $value;
-
}
- close FH;
+ close $fh;
$main::lxdebug->leave_sub(2);
sub init_sub_layouts {
[
SL::Layout::None->new,
- SL::Layout::CssMenu->new(menu => Menu->new('menus/admin.ini')),
+ SL::Layout::CssMenu->new(menu => SL::Menu->new('admin')),
]
}
}
sub init_menu {
- my @menu_files = qw(menus/erp.ini);
- 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 strict;
use parent qw(SL::Layout::Base);
-use URI;
-
-sub print_menu {
- my ($self, $parent, $depth) = @_;
-
- my $html;
-
- die if ($depth * 1 > 5);
-
- my @menuorder;
- my $menu = $self->menu;
-
- @menuorder = $menu->access_control(\%::myconfig, $parent);
-
- $parent .= "--" if ($parent);
-
- foreach my $item (@menuorder) {
- substr($item, 0, length($parent)) = "";
- next if (($item eq "") || ($item =~ /--/));
-
- my $menu_item = $menu->{"${parent}${item}"};
- my $menu_title = $::locale->text($item);
- my $menu_text = $menu_title;
-
- if ($menu_item->{"submenu"} || !defined($menu_item->{"module"}) && !defined($menu_item->{href})) {
-
- my $h = $self->print_menu("${parent}${item}", $depth * 1 + 1)."\n";
- if (!$parent) {
- $html .= qq|<ul><li><h2>${menu_text}</h2><ul>${h}</ul></li></ul>\n|;
- } else {
- $html .= qq|<li><div class="x">${menu_text}</div><ul>${h}</ul></li>\n|;
- }
- } else {
- if ($self->{sub_class} && $depth > 1) {
- $html .= qq|<li class='sub'>|;
- } else {
- $html .= qq|<li>|;
- }
- $html .= $self->menuitem_v3("${parent}$item", { "title" => $menu_title });
- $html .= qq|${menu_text}</a></li>\n|;
- }
- }
-
- return $html;
-}
-
-sub menuitem_v3 {
- $main::lxdebug->enter_sub();
-
- my ($self, $item, $other) = @_;
- my $menuitem = $self->menu->{$item};
-
- my $action = "section_menu";
- my $module;
-
- if ($menuitem->{module}) {
- $module = $menuitem->{module};
- }
- if ($menuitem->{action}) {
- $action = $menuitem->{action};
- }
-
- my $level = $::form->escape($item);
-
- my @vars;
- my $target = $menuitem->{target} ? qq| target="| . $::form->escape($menuitem->{target}) . '"' : '';
- my $str = qq|<a${target} href="|;
-
- if ($menuitem->{href}) {
- $main::lxdebug->leave_sub();
- return $str . $menuitem->{href} . '">';
- }
-
- $str .= qq|$module?action=| . $::form->escape($action);
-
- map { delete $menuitem->{$_} } qw(module action target href);
-
- # add other params
- foreach my $key (keys %{ $menuitem }) {
- $str .= "&" . $::form->escape($key, 1) . "=";
- my ($value, $conf) = split(/=/, $menuitem->{$key}, 2);
- $value = $::myconfig{$value} . "/$conf" if ($conf);
- $str .= $::form->escape($value, 1);
- }
-
- $str .= '"';
-
- if ($other) {
- foreach my $key (keys(%{$other})) {
- $str .= qq| ${key}="| . $::form->quote($other->{$key}) . qq|"|;
- }
- }
-
- $str .= ">";
-
- $main::lxdebug->leave_sub();
-
- return $str;
-}
-
sub use_stylesheet {
qw(icons16.css frame_header/header.css),
}
sub pre_content {
- $_[0]->presenter->render('menu/menuv3',
- menu => $_[0]->print_menu,
- );
+ $_[0]->presenter->render('menu/menuv3', menu => $_[0]->menu);
}
1;
$self->SUPER::use_javascript(@_);
}
+sub javascripts_inline {
+ $_[0]->SUPER::javascripts_inline,
+<<'EOJS'
+ DHTMLSuite.createStandardObjects();
+ DHTMLSuite.configObj.setImagePath('image/dhtmlsuite/');
+ var menu_model = new DHTMLSuite.menuModel();
+ menu_model.addItemsFromMarkup('main_menu_model');
+ menu_model.init();
+ var menu_bar = new DHTMLSuite.menuBar();
+ menu_bar.addMenuItems(menu_model);
+ menu_bar.setTarget('main_menu_div');
+ menu_bar.init();
+EOJS
+}
+
sub pre_content {
$_[0]->SUPER::pre_content .
- &display
+ $_[0]->presenter->render("menu/menunew",
+ force_ul_width => 1,
+ menu => $_[0]->menu,
+ icon_path => sub { my $img = "image/icons/16x16/$_[0].png"; -f $img ? $img : () },
+ max_width => sub { 10 * max map { length $::locale->text($_->{name}) } @{ $_[0]{children} || [] } },
+ );
}
sub start_content {
$_[0]->SUPER::stylesheets;
}
-sub display {
- my ($self) = @_;
-
- $self->presenter->render("menu/menunew",
- force_ul_width => 1,
- menu_items => $self->acc_menu,
- );
-}
-
-sub acc_menu {
- my ($self) = @_;
-
- my $menu = $self->menu;
-
- my $all_items = [];
- $self->create_menu($menu, $all_items);
-
- my $item = { 'subitems' => $all_items };
- calculate_width($item);
-
- return $all_items;
-}
-
-sub calculate_width {
- my $item = shift;
-
- $item->{max_width} = max map { length $_->{title} } @{ $item->{subitems} };
-
- foreach my $subitem (@{ $item->{subitems} }) {
- calculate_width($subitem) if ($subitem->{subitems});
- }
-}
-
-sub create_menu {
- my ($self, $menu, $all_items, $parent, $depth) = @_;
- my $html;
-
- my $form = $main::form;
- my %myconfig = %main::myconfig;
-
- $depth ||= 0;
-
- die if ($depth * 1 > 5);
-
- my @menuorder = $menu->access_control(\%myconfig, $parent);
- $parent .= "--" if ($parent);
- $parent ||= '';
-
- foreach my $name (@menuorder) {
- substr($name, 0, length($parent), "");
- next if (($name eq "") || ($name =~ /--/));
-
- my $menu_item = $menu->{"${parent}${name}"};
- my $item = { 'title' => $::locale->text($name) };
- push @{ $all_items }, $item;
-
- if ($menu_item->{submenu} || (!defined($menu_item->{module}) && !defined($menu_item->{href}))) {
- $item->{subitems} = [];
- $item->{image} = _icon_path("$name.png");
- $self->create_menu($menu, $item->{subitems}, "${parent}${name}", $depth * 1 + 1);
-
- } else {
- $item->{image} = _icon_path("${parent}${name}.png");
- $menu->menuitem_new("${parent}${name}", $item);
- }
- }
-}
-
-sub _icon_path {
- my ($label, $size) = @_;
-
- $size ||= 16;
-
- my $img = "image/icons/${size}x${size}/$label";
-
- return unless -f $img;
- return $img;
-}
-
1;
}
sub section_menu {
- $::lxdebug->enter_sub(2);
- my ($menu, $level, $id_prefix) = @_;
- my @menuorder = $menu->access_control(\%::myconfig, $level);
+ my ($menu) = @_;
my @items;
+ my @id_stack = (-1);
- my $id = 0;
+ for my $node ($menu->tree_walk) {
+ my $level = $node->{level};
- for my $item (@menuorder) {
- my $menuitem = $menu->{$item};
- my $olabel = apply { s/.*--// } $item;
- my $ml = apply { s/--.*// } $item;
- my $icon_class = apply { $_ =lc $_; s/[^a-z0-9_-]/-/g } $item;
- my $spacer = "s" . (0 + $item =~ s/--/--/g);
+ # do id stack
+ push @id_stack, -1 if $level > $#id_stack;
+ pop @id_stack while $level < $#id_stack;
+ $id_stack[-1]++;
- next if $level && $item ne "$level--$olabel";
+ my $label = $::locale->text($node->{name});
+ my $href = $menu->href_for_node($node);
- my $label = $::locale->text($olabel);
+ my @common_args = ($label, "s" . $level, join '_', @id_stack);
- $menuitem->{module} ||= $::form->{script};
- $menuitem->{action} ||= "section_menu";
- $menuitem->{href} ||= "$menuitem->{module}?action=$menuitem->{action}";
-
- # add other params
- foreach my $key (keys %$menuitem) {
- next if $key =~ /target|module|action|href/;
- $menuitem->{href} .= "&" . $::form->escape($key, 1) . "=";
- my ($value, $conf) = split(/=/, $menuitem->{$key}, 2);
- $value = $::myconfig{$value} . "/$conf" if ($conf);
- $menuitem->{href} .= $::form->escape($value, 1);
- }
-
- my @common_args = ($label, $spacer, "$id_prefix\_$id");
-
- if (!$level) { # toplevel
- push @items, [ @common_args, "icon24 $icon_class", 'm' ];
- # make_image(size => 24, label => $item),
- push @items, section_menu($menu, $item, "$id_prefix\_$id");
- } elsif ($menuitem->{submenu}) {
+ if (!$node->{parent}) { # toplevel
+ push @items, [ @common_args, "icon24 $node->{icon}", 'm' ];
+ } elsif ($node->{children}) {
push @items, [ @common_args, "icon16 submenu", 'sm' ];
- #make_image(label => 'submenu'),
- push @items, section_menu($menu, $item, "$id_prefix\_$id");
- } elsif ($menuitem->{module}) {
- push @items, [ @common_args, "icon16 $icon_class", 'i', $menuitem->{href}, $menuitem->{target} ];
- #make_image(size => 16, label => $item),
+ } else {
+ push @items, [ @common_args, "icon16 $node->{icon}", 'i', $href, $node->{target} ];
}
- } continue {
- $id++;
}
- $::lxdebug->leave_sub(2);
return @items;
}
$self->{countrycode} = $country;
if ($country && -d "locale/$country") {
- local *IN;
- if (open(IN, "<", "locale/$country/all")) {
- my $code = join("", <IN>);
+ if (open my $in, "<", "locale/$country/all") {
+ local $/ = undef;
+ my $code = <$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;
+ close $dh;
+
+ for my $file (@files) {
+ if (open my $in, "<", "locale/$country/more/$file") {
+ local $/ = undef;
+ my $code = <$file>;
+ eval($code);
+ close($in);
+ $self->{texts}{$_} = $self->{more_texts}{$_} for keys %{ $self->{more_texts} };
+ }
+ }
}
}
-#=====================================================================
-# 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) 2001
-#
-# Author: Dieter Simader
-# Email: dsimader@sql-ledger.org
-# Web: http://www.sql-ledger.org
-#
-# Contributors:
-#
-# 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.
-#=====================================================================
-#
-# routines for menu items
-#
-#=====================================================================
-
-package Menu;
+package SL::Menu;
+
+use strict;
use SL::Auth;
-use SL::Inifile;
+use YAML ();
+use File::Spec;
+use SL::MoreCommon qw(uri_encode);
-use strict;
+our $yaml_xs;
+BEGIN {
+ $yaml_xs = eval { require YAML::XS };
+}
+
+our %menu_cache;
sub new {
- $main::lxdebug->enter_sub();
+ my ($package, $domain) = @_;
+
+ if (!$menu_cache{$domain}) {
+ my $path = File::Spec->catdir('menus', $domain);
+
+ opendir my $dir, $path or die "can't open $path: $!";
+ my @files = sort grep -f "$path/$_", readdir $dir;
+ close $dir;
+
+ my $nodes = [];
+ my $nodes_by_id = {};
+ for my $file (@files) {
+ my $data;
+ if ($yaml_xs) {
+ $data = YAML::XS::LoadFile(File::Spec->catfile($path, $file));
+ } else {
+ $data = YAML::LoadFile(File::Spec->catfile($path, $file));
+ }
+ _merge($nodes, $nodes_by_id, $data);
+ }
- my ($type, @menufiles) = @_;
- my $self = bless {}, $type;
- my @order;
+ my $self = bless {
+ nodes => $nodes,
+ by_id => $nodes_by_id,
+ }, $package;
- foreach my $menufile (grep { -f } @menufiles) {
- my $inifile = Inifile->new($menufile);
+ $self->build_tree;
- push @order, @{ delete($inifile->{ORDER}) || [] };
- $self->{$_} = $inifile->{$_} for keys %{ $inifile };
+ $menu_cache{$domain} = $self;
+ } else {
+ $menu_cache{$domain}->clear_access;
}
- $self->{ORDER} = \@order;
+ $menu_cache{$domain}->set_access;
- $self->set_access();
+ return $menu_cache{$domain};
+}
- $main::lxdebug->leave_sub();
+sub _merge {
+ my ($nodes, $by_id, $data) = @_;
- return $self;
-}
+ die 'not an array ref' unless $data && 'ARRAY' eq ref $data; # TODO check this sooner, to get better diag to user
-sub menuitem_new {
- $main::lxdebug->enter_sub(LXDebug::DEBUG2());
+ for my $node (@$data) {
+ my $id = $node->{id};
+
+ my $merge_to = $by_id->{$id};
+
+ if (!$merge_to) {
+ push @$nodes, $node;
+ $by_id->{$id} = $node;
+ next;
+ }
- my ($self, $name, $item) = @_;
+ # TODO make this a real recursive merge
+ # TODO add support for arrays
+
+ # merge keys except params
+ for my $key (keys %$node) {
+ if (ref $node->{$key}) {
+ if ('HASH' eq ref $node->{$key}) {
+ $merge_to->{$key} = {} if !exists $merge_to->{$key} || 'HASH' ne ref $merge_to->{$key};
+ for (keys %{ $node->{params} }) {
+ $merge_to->{$key}{$_} = $node->{params}{$_};
+ }
+ } else {
+ die "unsupported structure @{[ ref $node->{$key} ]}";
+ }
+ } else {
+ $merge_to->{$key} = $node->{$key};
+ }
+ }
+ }
+}
- my $form = $main::form;
- my $myconfig = \%main::myconfig;
+sub build_tree {
+ my ($self) = @_;
- my $module = $self->{$name}->{module} || $form->{script};
- my $action = $self->{$name}->{action};
+ # first, some sanity check. are all parents valid ids or empty?
+ for my $node ($self->nodes) {
+ next if !exists $node->{parent} || !$node->{parent} || $self->{by_id}->{$node->{id}};
+ die "menu: node $node->{id} has non-existent parent $node->{parent}";
+ }
- $item->{target} = $self->{$name}->{target} || "main_window";
- $item->{href} = $self->{$name}->{href} || "${module}?action=" . $form->escape($action);
+ my %by_parent;
+ # order them by parent
+ for my $node ($self->nodes) {
+ push @{ $by_parent{ $node->{parent} } //= [] }, $node;
+ }
- my @vars = qw(module target href);
- push @vars, 'action' unless ($self->{$name}->{href});
+ my $tree = { };
+ $self->{by_id}{''} = $tree;
- map { delete $self->{$name}{$_} } @vars;
- # add other params
- foreach my $key (keys %{ $self->{$name} }) {
- my ($value, $conf) = split(m/=/, $self->{$name}->{$key}, 2);
- $value = $myconfig->{$value} . "/$conf" if ($conf);
- $item->{href} .= "&" . $form->escape($key) . "=" . $form->escape($value);
+ for (keys %by_parent) {
+ my $parent = $self->{by_id}{$_};
+ $parent->{children} = [ sort { $a->{order} <=> $b->{order} } @{ $by_parent{$_} } ];
}
- $main::lxdebug->leave_sub(LXDebug::DEBUG2());
+ _set_level_rec($tree->{children}, 0);
+
+ $self->{tree} = $tree->{children};
}
-sub access_control {
- $main::lxdebug->enter_sub(2);
+sub _set_level_rec {
+ my ($ary_ref, $level) = @_;
- my ($self, $myconfig, $menulevel) = @_;
+ for (@$ary_ref) {
+ $_->{level} = $level;
+ _set_level_rec($_->{children}, $level + 1) if $_->{children};
+ }
+}
- my @menu = ();
+sub nodes {
+ @{ $_[0]{nodes} }
+}
- if (!$menulevel) {
- @menu = grep { !/--/ } @{ $self->{ORDER} };
- } else {
- @menu = grep { /^${menulevel}--/ } @{ $self->{ORDER} };
- }
+sub tree_walk {
+ my ($self, $all) = @_;
- $main::lxdebug->leave_sub(2);
+ _tree_walk_rec($self->{tree}, $all);
+}
- return @menu;
+sub _tree_walk_rec {
+ my ($ary_ref, $all) = @_;
+ map { $_->{children} ? ($_, _tree_walk_rec($_->{children}, $all)) : ($_) } grep { $all || $_->{visible} } @$ary_ref;
}
sub parse_access_string {
- my $self = shift;
- my $key = shift;
- my $access = shift;
-
- my $form = $main::form;
- my $auth = $main::auth;
- my $myconfig = \%main::myconfig;
+ my ($self, $node) = @_;
my @stack;
my $cur_ary = [];
push @stack, $cur_ary;
- while ($access =~ m/^([a-z_]+|\||\&|\(|\)|\s+)/) {
+ my $access = $node->{access};
+
+ while ($access =~ m/^([a-z_\/]+|\||\&|\(|\)|\s+)/) {
my $token = $1;
substr($access, 0, length($1)) = "";
} elsif ($token eq ")") {
pop @stack;
if (!@stack) {
- $form->error("Error in menu.ini for entry ${key}: missing '('");
+ die "Error while parsing menu entry $node->{id}: missing '('";
}
$cur_ary = $stack[-1];
push @{$cur_ary}, $token;
} else {
- push @{$cur_ary}, $auth->check_right($::myconfig{login}, $token, 1);
+ if ($token =~ m{^ client / (.*) }x) {
+ push @{$cur_ary}, $self->parse_instance_conf_string($1);
+ } else {
+ push @{$cur_ary}, $::auth->check_right($::myconfig{login}, $token, 1);
+ }
}
}
if ($access) {
- $form->error("Error in menu.ini for entry ${key}: unrecognized token at the start of '$access'\n");
+ die "Error while parsing menu entry $node->{id}: unrecognized token at the start of '$access'\n";
}
if (1 < scalar @stack) {
- $main::form->error("Error in menu.ini for entry ${key}: Missing ')'\n");
+ die "Error while parsing menu entry $node->{id}: Missing ')'\n";
}
return SL::Auth::evaluate_rights_ary($stack[0]);
}
-sub parse_instance_conf_string {
- my ($self, $setting) = @_;
- return $::instance_conf->data->{$setting};
-}
+sub href_for_node {
+ my ($self, $node) = @_;
-sub set_access {
- my $self = shift;
-
- my $key;
-
- foreach $key (@{ $self->{ORDER} }) {
- my $entry = $self->{$key};
+ return undef if !$node->{href} && !$node->{module} && !$node->{params};
- $entry->{GRANTED} = $entry->{ACCESS} ? $self->parse_access_string($key, $entry->{ACCESS}) : 1;
- $entry->{GRANTED} &&= $self->parse_instance_conf_string($entry->{INSTANCE_CONF}) if $entry->{INSTANCE_CONF};
- $entry->{IS_MENU} = $entry->{submenu} || ($key !~ m/--/);
- $entry->{NUM_VISIBLE_CHILDREN} = 0;
+ my $href = $node->{href} || $node->{module} || 'controller.pl';
+ my @tokens;
- if ($key =~ m/--/) {
- my $parent = $key;
- substr($parent, rindex($parent, '--')) = '';
- $entry->{GRANTED} &&= $self->{$parent}->{GRANTED};
- }
-
- $entry->{VISIBLE} = $entry->{GRANTED};
+ while (my ($key, $value) = each %{ $node->{params} }) {
+ push @tokens, uri_encode($key, 1) . "=" . uri_encode($value, 1);
}
- foreach $key (reverse @{ $self->{ORDER} }) {
- my $entry = $self->{$key};
-
- if ($entry->{IS_MENU}) {
- $entry->{VISIBLE} &&= $entry->{NUM_VISIBLE_CHILDREN} > 0;
- }
-
- next if (($key !~ m/--/) || !$entry->{VISIBLE});
-
- my $parent = $key;
- substr($parent, rindex($parent, '--')) = '';
- $self->{$parent}->{NUM_VISIBLE_CHILDREN}++;
- }
+ return join '?', $href, grep $_, join '&', @tokens;
+}
-# $self->dump_visible();
+sub name_for_node {
+ $::locale->text($_[1]{name})
+}
- $self->{ORDER} = [ grep { $self->{$_}->{VISIBLE} } @{ $self->{ORDER} } ];
+sub parse_instance_conf_string {
+ my ($self, $setting) = @_;
+ return $::instance_conf->data->{$setting};
+}
- { no strict 'refs';
- # ToDO: fix this. nuke and pave algorithm without type checking screams for problems.
- map { delete @{$self->{$_}}{qw(GRANTED IS_MENU NUM_VISIBLE_CHILDREN VISIBLE ACCESS)} if ($_ ne 'ORDER') } keys %{ $self };
+sub clear_access {
+ my ($self) = @_;
+ for my $node ($self->tree_walk("all")) {
+ delete $node->{visible};
+ delete $node->{visible_children};
}
}
-sub dump_visible {
- my $self = shift;
- foreach my $key (@{ $self->{ORDER} }) {
- my $entry = $self->{$key};
- $main::lxdebug->message(0, "$entry->{GRANTED} $entry->{VISIBLE} $entry->{NUM_VISIBLE_CHILDREN} $key");
+sub set_access {
+ my ($self) = @_;
+ # 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->{access} ? $self->parse_access_string($node)
+ : !$node->{children} ? 1
+ : $node->{visible_children} ? 1
+ : 0;
+ if ($node->{visible} && $node->{parent}) {
+ $self->{by_id}{ $node->{parent} }{visible_children} = 1;
+ }
}
}
UPDATE orderitems SET
trans_id = ?, position = ?, parts_id = ?, description = ?, longdescription = ?, qty = ?, base_qty = ?,
sellprice = ?, discount = ?, unit = ?, reqdate = ?, project_id = ?, serialnumber = ?, ship = ?,
- pricegroup_id = ?, ordnumber = ?, transdate = ?, cusordnumber = ?, subtotal = ?,
+ pricegroup_id = ?, subtotal = ?,
marge_percent = ?, marge_total = ?, lastcost = ?, price_factor_id = ?,
active_price_source = ?, active_discount_source = ?,
price_factor = (SELECT factor FROM price_factors WHERE id = ?), marge_price_factor = ?
$form->{"qty_$i"}, $baseqty,
$fxsellprice, $form->{"discount_$i"},
$form->{"unit_$i"}, conv_date($reqdate), conv_i($form->{"project_id_$i"}),
- $form->{"serialnumber_$i"}, $form->{"ship_$i"}, $pricegroup_id,
- $form->{"ordnumber_$i"}, conv_date($form->{"transdate_$i"}),
- $form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f',
+ $form->{"serialnumber_$i"}, $form->{"ship_$i"},
+ $pricegroup_id, $form->{"subtotal_$i"} ? 't' : 'f',
$form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"},
$form->{"lastcost_$i"}, conv_i($form->{"price_factor_id_$i"}),
$form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"},
# and remember for the rest of the function
my $is_collective_order = scalar @ids;
- $form->{useasnew} = !!$is_collective_order;
+
+ # If collective order was created from exactly 1 order, we assume the same
+ # behaviour as a "save as new" from within an order is actually desired, i.e.
+ # the original order isn't part of a workflow where we want to remember
+ # record_links, but simply a quick way of generating a new order from an old
+ # one without having to enter everything again.
+ # Setting useasnew will prevent the creation of record_links for the items
+ # when saving the new order.
+ # This form variable is probably not necessary, could just set saveasnew instead
+ $form->{useasnew} = 1 if $is_collective_order == 1;
if (!$form->{id}) {
my $extra_days = $form->{type} eq 'sales_quotation' ? $::instance_conf->get_reqdate_interval : 1;
}
# delete orderitems_id in collective orders, so that they get cloned no matter what
+ # is this correct? or is the following meant?
+ # remember orderitems_ids in converted_from_orderitems_ids, so that they may be linked
$ref->{converted_from_orderitems_id} = delete $ref->{orderitems_id} if $is_collective_order;
# get tax rates and description
if (scalar @{ $form->{CUSTOM_VARIABLES} });
$::request->layout->use_javascript("${_}.js") for qw(ckeditor/ckeditor ckeditor/adapters/jquery kivi.PriceRule);
- $::request->layout->add_javascripts_inline("\$(function(){kivi.PriceRule.load_price_rules_for_part(@{[ $::form->{id} * 1 ]})})") if $::form->{id};
+ $::request->layout->add_javascripts_inline("\$(function(){kivi.PriceRule.load_price_rules_for_part(@{[ $::form->{id} * 1 ]})});") if $::form->{id};
$form->header;
#print $form->parse_html_template('ic/form_header', { ALL_PRICE_FACTORS => $form->{ALL_PRICE_FACTORS},
# ALL_UNITS => $form->{ALL_UNITS},
format_dates($output_dateformat, $output_longdates,
qw(invdate orddate quodate pldate duedate reqdate transdate
shippingdate deliverydate validitydate paymentdate
- datepaid transdate_oe deliverydate_oe dodate
+ datepaid transdate_oe transdate_do transdate_quo deliverydate_oe dodate
employee_startdate employee_enddate
),
grep({ /^datepaid_\d+$/ ||
/^transdate_oe_\d+$/ ||
+ /^transdate_do_\d+$/ ||
+ /^transdate_quo_\d+$/ ||
/^deliverydate_oe_\d+$/ ||
/^reqdate_\d+$/ ||
/^deliverydate_\d+$/ ||
.icon16 { background: url(../image/maps/icons16.png) 16px 0px no-repeat; padding: 0; width: 16px; height: 16px; }
-.icon16.ap--add-purchase-order { background-position: -0px 0px; }
-.icon16.ap--add-rfq { background-position: -16px 0px; }
-.icon16.ap { background-position: -32px 0px; }
-.icon16.ap--reports { background-position: -48px 0px; }
-.icon16.ap--reports--purchase-orders { background-position: -64px 0px; }
-.icon16.ap--reports--rfqs { background-position: -80px 0px; }
-.icon16.ar--add-credit-note { background-position: -96px 0px; }
-.icon16.ar--add-delivery-order { background-position: -112px 0px; }
-.icon16.ar--add-dunning { background-position: -128px 0px; }
-.icon16.ar--add-quotation { background-position: -144px 0px; }
-.icon16.ar--add-sales-invoice { background-position: -160px 0px; }
-.icon16.ar--add-sales-order { background-position: -176px 0px; }
-.icon16.ar { background-position: -192px 0px; }
-.icon16.ar--reports--delivery-orders { background-position: -208px 0px; }
-.icon16.ar--reports--dunnings { background-position: -224px 0px; }
-.icon16.ar--reports--invoices--credit-notes---ar-transactions { background-position: -240px 0px; }
-.icon16.ar--reports { background-position: -256px 0px; }
-.icon16.ar--reports--quotations { background-position: -272px 0px; }
-.icon16.ar--reports--sales-orders { background-position: -288px 0px; }
-.icon16.batch-printing--packing-lists { background-position: -304px 0px; }
-.icon16.batch-printing { background-position: -320px 0px; }
-.icon16.batch-printing--purchase-orders { background-position: -336px 0px; }
-.icon16.batch-printing--quotations { background-position: -352px 0px; }
-.icon16.batch-printing--receipts { background-position: -368px 0px; }
-.icon16.batch-printing--rfqs { background-position: -384px 0px; }
-.icon16.batch-printing--sales-invoices { background-position: -400px 0px; }
-.icon16.batch-printing--sales-orders { background-position: -416px 0px; }
-.icon16.cash--payment { background-position: -432px 0px; }
-.icon16.cash { background-position: -448px 0px; }
-.icon16.cash--receipt { background-position: -464px 0px; }
-.icon16.cash--reconciliation { background-position: -480px 0px; }
-.icon16.cash--reports--payments { background-position: -496px 0px; }
-.icon16.cash--reports { background-position: -512px 0px; }
-.icon16.cash--reports--receipts { background-position: -528px 0px; }
-.icon16.crm--add--customer { background-position: -544px 0px; }
-.icon16.crm--add--person { background-position: -560px 0px; }
-.icon16.crm--add--vendor { background-position: -576px 0px; }
-.icon16.crm--admin--document-template { background-position: -592px 0px; }
-.icon16.crm--admin--label { background-position: -608px 0px; }
-.icon16.crm--admin--message { background-position: -624px 0px; }
-.icon16.crm--admin { background-position: -640px 0px; }
-.icon16.crm--admin--status { background-position: -656px 0px; }
-.icon16.crm--admin--user-groups { background-position: -672px 0px; }
-.icon16.crm--admin--user { background-position: -688px 0px; }
-.icon16.crm--appointments { background-position: -704px 0px; }
-.icon16.crm--e-mail { background-position: -720px 0px; }
-.icon16.crm--follow-up { background-position: -736px 0px; }
-.icon16.crm--help { background-position: -752px 0px; }
-.icon16.crm--knowledge { background-position: -768px 0px; }
-.icon16.crm--memo { background-position: -784px 0px; }
-.icon16.crm--opportunity { background-position: -800px 0px; }
-.icon16.crm { background-position: -816px 0px; }
-.icon16.crm--search { background-position: -832px 0px; }
-.icon16.crm--service { background-position: -848px 0px; }
-.icon16.general-ledger--add-ap-transaction { background-position: -864px 0px; }
-.icon16.general-ledger--add-ar-transaction { background-position: -880px 0px; }
-.icon16.general-ledger--add-transaction { background-position: -896px 0px; }
-.icon16.general-ledger--datev---export-assistent { background-position: -912px 0px; }
-.icon16.general-ledger { background-position: -928px 0px; }
-.icon16.general-ledger--reports--ap-aging { background-position: -944px 0px; }
-.icon16.general-ledger--reports--ar-aging { background-position: -960px 0px; }
-.icon16.general-ledger--reports--journal { background-position: -976px 0px; }
-.icon16.general-ledger--reports { background-position: -992px 0px; }
-.icon16.master-data--add-assembly { background-position: -1008px 0px; }
-.icon16.master-data--add-customer { background-position: -1024px 0px; }
-.icon16.master-data--add-license { background-position: -1040px 0px; }
-.icon16.master-data--add-part { background-position: -1056px 0px; }
-.icon16.master-data--add-project { background-position: -1072px 0px; }
-.icon16.master-data--add-service { background-position: -1088px 0px; }
-.icon16.master-data--add-vendor { background-position: -1104px 0px; }
-.icon16.master-data { background-position: -1120px 0px; }
-.icon16.master-data--reports--assemblies { background-position: -1136px 0px; }
-.icon16.master-data--reports--customers { background-position: -1152px 0px; }
-.icon16.master-data--reports--licenses { background-position: -1168px 0px; }
-.icon16.master-data--reports--parts { background-position: -1184px 0px; }
-.icon16.master-data--reports { background-position: -1200px 0px; }
-.icon16.master-data--reports--projects { background-position: -1216px 0px; }
-.icon16.master-data--reports--projecttransactions { background-position: -1232px 0px; }
-.icon16.master-data--reports--services { background-position: -1248px 0px; }
-.icon16.master-data--reports--vendors { background-position: -1264px 0px; }
-.icon16.master-data--update-prices { background-position: -1280px 0px; }
-.icon16.mdi-text-editor-16x16 { background-position: -1296px 0px; }
-.icon16.neues-fenster { background-position: -1312px 0px; }
-.icon16.program--logout { background-position: -1328px 0px; }
-.icon16.program { background-position: -1344px 0px; }
-.icon16.program--preferences { background-position: -1360px 0px; }
-.icon16.program--version { background-position: -1376px 0px; }
-.icon16.reports--balance-sheet { background-position: -1392px 0px; }
-.icon16.reports--chart-of-accounts { background-position: -1408px 0px; }
-.icon16.reports--income-statement { background-position: -1424px 0px; }
-.icon16.reports { background-position: -1440px 0px; }
-.icon16.reports--ustva { background-position: -1456px 0px; }
-.icon16.system { background-position: -1472px 0px; }
-.icon16.warehouse { background-position: -1488px 0px; }
-.icon16.warehouse--produce-assembly { background-position: -1504px 0px; }
+.icon16.admin { background-position: -0px 0px; }
+.icon16.ap { background-position: -16px 0px; }
+.icon16.ap_aging { background-position: -32px 0px; }
+.icon16.ap_report { background-position: -48px 0px; }
+.icon16.ap_transaction_add { background-position: -64px 0px; }
+.icon16.appointment { background-position: -80px 0px; }
+.icon16.ar { background-position: -96px 0px; }
+.icon16.ar_aging { background-position: -112px 0px; }
+.icon16.ar_report { background-position: -128px 0px; }
+.icon16.ar_transaction_add { background-position: -144px 0px; }
+.icon16.assembly_add { background-position: -160px 0px; }
+.icon16.assembly_produce { background-position: -176px 0px; }
+.icon16.assembly_report { background-position: -192px 0px; }
+.icon16.balance_sheet { background-position: -208px 0px; }
+.icon16.cash { background-position: -224px 0px; }
+.icon16.cash_report { background-position: -240px 0px; }
+.icon16.chart_of_accounts { background-position: -256px 0px; }
+.icon16.contact { background-position: -272px 0px; }
+.icon16.credit_note_add { background-position: -288px 0px; }
+.icon16.crm { background-position: -304px 0px; }
+.icon16.customer { background-position: -320px 0px; }
+.icon16.customer_add { background-position: -336px 0px; }
+.icon16.customer_report { background-position: -352px 0px; }
+.icon16.datev { background-position: -368px 0px; }
+.icon16.delivery_order_add { background-position: -384px 0px; }
+.icon16.delivery_order_report { background-position: -400px 0px; }
+.icon16.document_template { background-position: -416px 0px; }
+.icon16.dunning_add { background-position: -432px 0px; }
+.icon16.dunnings_report { background-position: -448px 0px; }
+.icon16.email { background-position: -464px 0px; }
+.icon16.follow_up { background-position: -480px 0px; }
+.icon16.gl { background-position: -496px 0px; }
+.icon16.gl_report { background-position: -512px 0px; }
+.icon16.help { background-position: -528px 0px; }
+.icon16.income_statement { background-position: -544px 0px; }
+.icon16.invoices_report { background-position: -560px 0px; }
+.icon16.journal { background-position: -576px 0px; }
+.icon16.knowledge { background-position: -592px 0px; }
+.icon16.label { background-position: -608px 0px; }
+.icon16.license_add { background-position: -624px 0px; }
+.icon16.license_report { background-position: -640px 0px; }
+.icon16.logout { background-position: -656px 0px; }
+.icon16.master_data { background-position: -672px 0px; }
+.icon16.master_data_report { background-position: -688px 0px; }
+.icon16.mdi_text_editor { background-position: -704px 0px; }
+.icon16.memo { background-position: -720px 0px; }
+.icon16.message { background-position: -736px 0px; }
+.icon16.opportunity { background-position: -752px 0px; }
+.icon16.package_lists { background-position: -768px 0px; }
+.icon16.part_add { background-position: -784px 0px; }
+.icon16.part_report { background-position: -800px 0px; }
+.icon16.payment { background-position: -816px 0px; }
+.icon16.payment_report { background-position: -832px 0px; }
+.icon16.phone { background-position: -848px 0px; }
+.icon16.preferences { background-position: -864px 0px; }
+.icon16.prices_update { background-position: -880px 0px; }
+.icon16.printing { background-position: -896px 0px; }
+.icon16.program { background-position: -912px 0px; }
+.icon16.project_add { background-position: -928px 0px; }
+.icon16.project_report { background-position: -944px 0px; }
+.icon16.project_transaction_report { background-position: -960px 0px; }
+.icon16.purchase_order_add { background-position: -976px 0px; }
+.icon16.purchase_order_printing { background-position: -992px 0px; }
+.icon16.purchase_order_report { background-position: -1008px 0px; }
+.icon16.quotation_add { background-position: -1024px 0px; }
+.icon16.quotation_printing { background-position: -1040px 0px; }
+.icon16.receipt { background-position: -1056px 0px; }
+.icon16.receipt_printing { background-position: -1072px 0px; }
+.icon16.receipt_report { background-position: -1088px 0px; }
+.icon16.reconcilliation { background-position: -1104px 0px; }
+.icon16.report { background-position: -1120px 0px; }
+.icon16.report_quotations { background-position: -1136px 0px; }
+.icon16.report_sales_orders { background-position: -1152px 0px; }
+.icon16.rfq_add { background-position: -1168px 0px; }
+.icon16.rfq_printing { background-position: -1184px 0px; }
+.icon16.rfq_report { background-position: -1200px 0px; }
+.icon16.sales_invoice_add { background-position: -1216px 0px; }
+.icon16.sales_invoice_printing { background-position: -1232px 0px; }
+.icon16.sales_order_add { background-position: -1248px 0px; }
+.icon16.sales_order_printing { background-position: -1264px 0px; }
+.icon16.search { background-position: -1280px 0px; }
+.icon16.service { background-position: -1296px 0px; }
+.icon16.service_add { background-position: -1312px 0px; }
+.icon16.service_report { background-position: -1328px 0px; }
+.icon16.status { background-position: -1344px 0px; }
+.icon16.system { background-position: -1360px 0px; }
+.icon16.transaction_add { background-position: -1376px 0px; }
+.icon16.user { background-position: -1392px 0px; }
+.icon16.user_group { background-position: -1408px 0px; }
+.icon16.ustva { background-position: -1424px 0px; }
+.icon16.vendor { background-position: -1440px 0px; }
+.icon16.vendor_add { background-position: -1456px 0px; }
+.icon16.vendor_report { background-position: -1472px 0px; }
+.icon16.version { background-position: -1488px 0px; }
+.icon16.warehouse { background-position: -1504px 0px; }
+.icon16.window_new { background-position: -1520px 0px; }
.icon24 { background: url(../image/maps/icons24.png) 24px 0px no-repeat; padding: 0; width: 24px; height: 24px; }
-.icon24.ap--add-purchase-order { background-position: -0px 0px; }
-.icon24.ap--add-rfq { background-position: -24px 0px; }
-.icon24.ap { background-position: -48px 0px; }
-.icon24.ap--reports { background-position: -72px 0px; }
-.icon24.ap--reports--purchase-orders { background-position: -96px 0px; }
-.icon24.ap--reports--rfqs { background-position: -120px 0px; }
-.icon24.ar--add-dunning { background-position: -144px 0px; }
-.icon24.ar--add-quotation { background-position: -168px 0px; }
-.icon24.ar--add-sales-invoice { background-position: -192px 0px; }
-.icon24.ar--add-sales-order { background-position: -216px 0px; }
-.icon24.ar { background-position: -240px 0px; }
-.icon24.ar--reports--dunnings { background-position: -264px 0px; }
-.icon24.ar--reports--invoices { background-position: -288px 0px; }
-.icon24.ar--reports { background-position: -312px 0px; }
-.icon24.ar--reports--quotations { background-position: -336px 0px; }
-.icon24.ar--reports--sales-orders { background-position: -360px 0px; }
-.icon24.batch-printing--packing-lists { background-position: -384px 0px; }
-.icon24.batch-printing { background-position: -408px 0px; }
-.icon24.batch-printing--purchase-orders { background-position: -432px 0px; }
-.icon24.batch-printing--quotations { background-position: -456px 0px; }
-.icon24.batch-printing--receipts { background-position: -480px 0px; }
-.icon24.batch-printing--rfqs { background-position: -504px 0px; }
-.icon24.batch-printing--sales-invoices { background-position: -528px 0px; }
-.icon24.batch-printing--sales-orders { background-position: -552px 0px; }
-.icon24.cash--payment { background-position: -576px 0px; }
-.icon24.cash { background-position: -600px 0px; }
-.icon24.cash--receipt { background-position: -624px 0px; }
-.icon24.cash--reconciliation { background-position: -648px 0px; }
-.icon24.cash--reports--payments { background-position: -672px 0px; }
-.icon24.cash--reports { background-position: -696px 0px; }
-.icon24.cash--reports--receipts { background-position: -720px 0px; }
-.icon24.crm--add--customer { background-position: -744px 0px; }
-.icon24.crm--add--person { background-position: -768px 0px; }
-.icon24.crm--add--vendor { background-position: -792px 0px; }
-.icon24.crm--admin--document-template { background-position: -816px 0px; }
-.icon24.crm--admin--label { background-position: -840px 0px; }
-.icon24.crm--admin--message { background-position: -864px 0px; }
-.icon24.crm--admin { background-position: -888px 0px; }
-.icon24.crm--admin--status { background-position: -912px 0px; }
-.icon24.crm--admin--user-groups { background-position: -936px 0px; }
-.icon24.crm--admin--user { background-position: -960px 0px; }
-.icon24.crm--appointments { background-position: -984px 0px; }
-.icon24.crm--email { background-position: -1008px 0px; }
-.icon24.crm--follow-up { background-position: -1032px 0px; }
-.icon24.crm--help { background-position: -1056px 0px; }
-.icon24.crm--knowledge { background-position: -1080px 0px; }
-.icon24.crm--memo { background-position: -1104px 0px; }
-.icon24.crm--opportunity { background-position: -1128px 0px; }
-.icon24.crm { background-position: -1152px 0px; }
-.icon24.crm--search { background-position: -1176px 0px; }
-.icon24.crm--service { background-position: -1200px 0px; }
-.icon24.general-ledger--add-ap-transaction { background-position: -1224px 0px; }
-.icon24.general-ledger--add-ar-transaction { background-position: -1248px 0px; }
-.icon24.general-ledger--add-transaction { background-position: -1272px 0px; }
-.icon24.general-ledger--datev---export-assistent { background-position: -1296px 0px; }
-.icon24.general-ledger { background-position: -1320px 0px; }
-.icon24.general-ledger--reports--ap-aging { background-position: -1344px 0px; }
-.icon24.general-ledger--reports--ar-aging { background-position: -1368px 0px; }
-.icon24.general-ledger--reports--journal { background-position: -1392px 0px; }
-.icon24.general-ledger--reports { background-position: -1416px 0px; }
-.icon24.leftarrow_24 { background-position: -1440px 0px; }
-.icon24.master-data--add-assembly { background-position: -1464px 0px; }
-.icon24.master-data--add-customer { background-position: -1488px 0px; }
-.icon24.master-data--add-license { background-position: -1512px 0px; }
-.icon24.master-data--add-part { background-position: -1536px 0px; }
-.icon24.master-data--add-project { background-position: -1560px 0px; }
-.icon24.master-data--add-service { background-position: -1584px 0px; }
-.icon24.master-data--add-vendor { background-position: -1608px 0px; }
-.icon24.master-data { background-position: -1632px 0px; }
-.icon24.master-data--reports--assemblies { background-position: -1656px 0px; }
-.icon24.master-data--reports--customers { background-position: -1680px 0px; }
-.icon24.master-data--reports--licenses { background-position: -1704px 0px; }
-.icon24.master-data--reports--parts { background-position: -1728px 0px; }
-.icon24.master-data--reports { background-position: -1752px 0px; }
-.icon24.master-data--reports--projects { background-position: -1776px 0px; }
-.icon24.master-data--reports--projecttransactions { background-position: -1800px 0px; }
-.icon24.master-data--reports--services { background-position: -1824px 0px; }
-.icon24.master-data--reports--vendors { background-position: -1848px 0px; }
-.icon24.neues-fenster { background-position: -1872px 0px; }
-.icon24.productivity { background-position: -1896px 0px; }
-.icon24.program--logout { background-position: -1920px 0px; }
-.icon24.program { background-position: -1944px 0px; }
-.icon24.program--preferences { background-position: -1968px 0px; }
-.icon24.program--version { background-position: -1992px 0px; }
-.icon24.reports--balance-sheet { background-position: -2016px 0px; }
-.icon24.reports--chart-of-accounts { background-position: -2040px 0px; }
-.icon24.reports--income-statement { background-position: -2064px 0px; }
-.icon24.reports { background-position: -2088px 0px; }
-.icon24.reports--ustva { background-position: -2112px 0px; }
-.icon24.rightarrow_24 { background-position: -2136px 0px; }
-.icon24.system { background-position: -2160px 0px; }
-.icon24.warehouse { background-position: -2184px 0px; }
+.icon24.admin { background-position: -0px 0px; }
+.icon24.ap { background-position: -24px 0px; }
+.icon24.ap_aging { background-position: -48px 0px; }
+.icon24.ap_report { background-position: -72px 0px; }
+.icon24.ap_transaction_add { background-position: -96px 0px; }
+.icon24.appointment { background-position: -120px 0px; }
+.icon24.ar { background-position: -144px 0px; }
+.icon24.ar_aging { background-position: -168px 0px; }
+.icon24.ar_report { background-position: -192px 0px; }
+.icon24.ar_transaction_add { background-position: -216px 0px; }
+.icon24.assembly_add { background-position: -240px 0px; }
+.icon24.assembly_report { background-position: -264px 0px; }
+.icon24.balance_sheet { background-position: -288px 0px; }
+.icon24.cash { background-position: -312px 0px; }
+.icon24.cash_report { background-position: -336px 0px; }
+.icon24.chart_of_accounts { background-position: -360px 0px; }
+.icon24.contact { background-position: -384px 0px; }
+.icon24.crm { background-position: -408px 0px; }
+.icon24.customer { background-position: -432px 0px; }
+.icon24.customer_add { background-position: -456px 0px; }
+.icon24.customer_report { background-position: -480px 0px; }
+.icon24.datev { background-position: -504px 0px; }
+.icon24.document_template { background-position: -528px 0px; }
+.icon24.dunning_add { background-position: -552px 0px; }
+.icon24.dunnings_report { background-position: -576px 0px; }
+.icon24.email { background-position: -600px 0px; }
+.icon24.follow_up { background-position: -624px 0px; }
+.icon24.gl { background-position: -648px 0px; }
+.icon24.gl_report { background-position: -672px 0px; }
+.icon24.help { background-position: -696px 0px; }
+.icon24.income_statement { background-position: -720px 0px; }
+.icon24.invoices_report { background-position: -744px 0px; }
+.icon24.journal { background-position: -768px 0px; }
+.icon24.knowledge { background-position: -792px 0px; }
+.icon24.label { background-position: -816px 0px; }
+.icon24.leftarrow_24 { background-position: -840px 0px; }
+.icon24.license_add { background-position: -864px 0px; }
+.icon24.license_report { background-position: -888px 0px; }
+.icon24.logout { background-position: -912px 0px; }
+.icon24.master_data { background-position: -936px 0px; }
+.icon24.master_data_report { background-position: -960px 0px; }
+.icon24.memo { background-position: -984px 0px; }
+.icon24.message { background-position: -1008px 0px; }
+.icon24.opportunity { background-position: -1032px 0px; }
+.icon24.package_lists { background-position: -1056px 0px; }
+.icon24.part_add { background-position: -1080px 0px; }
+.icon24.part_report { background-position: -1104px 0px; }
+.icon24.payment { background-position: -1128px 0px; }
+.icon24.payment_report { background-position: -1152px 0px; }
+.icon24.preferences { background-position: -1176px 0px; }
+.icon24.printing { background-position: -1200px 0px; }
+.icon24.productivity { background-position: -1224px 0px; }
+.icon24.program { background-position: -1248px 0px; }
+.icon24.project_add { background-position: -1272px 0px; }
+.icon24.project_report { background-position: -1296px 0px; }
+.icon24.project_transaction_report { background-position: -1320px 0px; }
+.icon24.purchase_order_add { background-position: -1344px 0px; }
+.icon24.purchase_order_printing { background-position: -1368px 0px; }
+.icon24.purchase_order_report { background-position: -1392px 0px; }
+.icon24.quotation_add { background-position: -1416px 0px; }
+.icon24.quotation_printing { background-position: -1440px 0px; }
+.icon24.receipt { background-position: -1464px 0px; }
+.icon24.receipt_printing { background-position: -1488px 0px; }
+.icon24.receipt_report { background-position: -1512px 0px; }
+.icon24.reconcilliation { background-position: -1536px 0px; }
+.icon24.report { background-position: -1560px 0px; }
+.icon24.report_quotations { background-position: -1584px 0px; }
+.icon24.report_sales_orders { background-position: -1608px 0px; }
+.icon24.rfq_add { background-position: -1632px 0px; }
+.icon24.rfq_printing { background-position: -1656px 0px; }
+.icon24.rfq_report { background-position: -1680px 0px; }
+.icon24.rightarrow_24 { background-position: -1704px 0px; }
+.icon24.sales_invoice_add { background-position: -1728px 0px; }
+.icon24.sales_invoice_printing { background-position: -1752px 0px; }
+.icon24.sales_order_add { background-position: -1776px 0px; }
+.icon24.sales_order_printing { background-position: -1800px 0px; }
+.icon24.search { background-position: -1824px 0px; }
+.icon24.service { background-position: -1848px 0px; }
+.icon24.service_add { background-position: -1872px 0px; }
+.icon24.service_report { background-position: -1896px 0px; }
+.icon24.status { background-position: -1920px 0px; }
+.icon24.system { background-position: -1944px 0px; }
+.icon24.transaction_add { background-position: -1968px 0px; }
+.icon24.user { background-position: -1992px 0px; }
+.icon24.user_group { background-position: -2016px 0px; }
+.icon24.ustva { background-position: -2040px 0px; }
+.icon24.vendor { background-position: -2064px 0px; }
+.icon24.vendor_add { background-position: -2088px 0px; }
+.icon24.vendor_report { background-position: -2112px 0px; }
+.icon24.version { background-position: -2136px 0px; }
+.icon24.warehouse { background-position: -2160px 0px; }
+.icon24.window_new { background-position: -2184px 0px; }
.icon32 { background: url(../image/maps/icons32.png) 32px 0px no-repeat; padding: 0; width: 32px; height: 32px; }
-.icon32.ap--add-purchase-order { background-position: -0px 0px; }
-.icon32.ap--add-rfq { background-position: -32px 0px; }
-.icon32.ap { background-position: -64px 0px; }
-.icon32.ap--reports { background-position: -96px 0px; }
-.icon32.ap--reports--purchase-orders { background-position: -128px 0px; }
-.icon32.ap--reports--rfqs { background-position: -160px 0px; }
-.icon32.ar--add-dunning { background-position: -192px 0px; }
-.icon32.ar--add-quotation { background-position: -224px 0px; }
-.icon32.ar--add-sales-invoice { background-position: -256px 0px; }
-.icon32.ar--add-sales-order { background-position: -288px 0px; }
-.icon32.ar { background-position: -320px 0px; }
-.icon32.ar--reports--dunnings { background-position: -352px 0px; }
-.icon32.ar--reports--invoices { background-position: -384px 0px; }
-.icon32.ar--reports { background-position: -416px 0px; }
-.icon32.ar--reports--quotations { background-position: -448px 0px; }
-.icon32.ar--reports--sales-orders { background-position: -480px 0px; }
-.icon32.batch-printing--packing-lists { background-position: -512px 0px; }
-.icon32.batch-printing { background-position: -544px 0px; }
-.icon32.batch-printing--purchase-orders { background-position: -576px 0px; }
-.icon32.batch-printing--quotations { background-position: -608px 0px; }
-.icon32.batch-printing--receipts { background-position: -640px 0px; }
-.icon32.batch-printing--rfqs { background-position: -672px 0px; }
-.icon32.batch-printing--sales-invoices { background-position: -704px 0px; }
-.icon32.batch-printing--sales-orders { background-position: -736px 0px; }
-.icon32.cash--payment { background-position: -768px 0px; }
-.icon32.cash { background-position: -800px 0px; }
-.icon32.cash--receipt { background-position: -832px 0px; }
-.icon32.cash--reconciliation { background-position: -864px 0px; }
-.icon32.cash--reports--payments { background-position: -896px 0px; }
-.icon32.cash--reports { background-position: -928px 0px; }
-.icon32.cash--reports--receipts { background-position: -960px 0px; }
-.icon32.crm--add--customer { background-position: -992px 0px; }
-.icon32.crm--add--person { background-position: -1024px 0px; }
-.icon32.crm--add--vendor { background-position: -1056px 0px; }
-.icon32.crm--admin--document-template { background-position: -1088px 0px; }
-.icon32.crm--admin--label { background-position: -1120px 0px; }
-.icon32.crm--admin--message { background-position: -1152px 0px; }
-.icon32.crm--admin { background-position: -1184px 0px; }
-.icon32.crm--admin--status { background-position: -1216px 0px; }
-.icon32.crm--admin--user-groups { background-position: -1248px 0px; }
-.icon32.crm--admin--user { background-position: -1280px 0px; }
-.icon32.crm--appointments { background-position: -1312px 0px; }
-.icon32.crm--email { background-position: -1344px 0px; }
-.icon32.crm--follow-up { background-position: -1376px 0px; }
-.icon32.crm--help { background-position: -1408px 0px; }
-.icon32.crm--knowledge { background-position: -1440px 0px; }
-.icon32.crm--memo { background-position: -1472px 0px; }
-.icon32.crm--opportunity { background-position: -1504px 0px; }
-.icon32.crm { background-position: -1536px 0px; }
-.icon32.crm--search { background-position: -1568px 0px; }
-.icon32.crm--service { background-position: -1600px 0px; }
-.icon32.general-ledger--add-ap-transaction { background-position: -1632px 0px; }
-.icon32.general-ledger--add-ar-transaction { background-position: -1664px 0px; }
-.icon32.general-ledger--add-transaction { background-position: -1696px 0px; }
-.icon32.general-ledger--datev---export-assistent { background-position: -1728px 0px; }
-.icon32.general-ledger { background-position: -1760px 0px; }
-.icon32.general-ledger--reports--ap-aging { background-position: -1792px 0px; }
-.icon32.general-ledger--reports--ar-aging { background-position: -1824px 0px; }
-.icon32.general-ledger--reports--journal { background-position: -1856px 0px; }
-.icon32.general-ledger--reports { background-position: -1888px 0px; }
-.icon32.master-data--add-assembly { background-position: -1920px 0px; }
-.icon32.master-data--add-customer { background-position: -1952px 0px; }
-.icon32.master-data--add-license { background-position: -1984px 0px; }
-.icon32.master-data--add-part { background-position: -2016px 0px; }
-.icon32.master-data--add-project { background-position: -2048px 0px; }
-.icon32.master-data--add-service { background-position: -2080px 0px; }
-.icon32.master-data--add-vendor { background-position: -2112px 0px; }
-.icon32.master-data { background-position: -2144px 0px; }
-.icon32.master-data--reports--assemblies { background-position: -2176px 0px; }
-.icon32.master-data--reports--customers { background-position: -2208px 0px; }
-.icon32.master-data--reports--licenses { background-position: -2240px 0px; }
-.icon32.master-data--reports--parts { background-position: -2272px 0px; }
-.icon32.master-data--reports { background-position: -2304px 0px; }
-.icon32.master-data--reports--projects { background-position: -2336px 0px; }
-.icon32.master-data--reports--projecttransactions { background-position: -2368px 0px; }
-.icon32.master-data--reports--services { background-position: -2400px 0px; }
-.icon32.master-data--reports--vendors { background-position: -2432px 0px; }
-.icon32.neues-fenster { background-position: -2464px 0px; }
-.icon32.program--logout { background-position: -2496px 0px; }
-.icon32.program { background-position: -2528px 0px; }
-.icon32.program--preferences { background-position: -2560px 0px; }
-.icon32.program--version { background-position: -2592px 0px; }
-.icon32.reports--balance-sheet { background-position: -2624px 0px; }
-.icon32.reports--chart-of-accounts { background-position: -2656px 0px; }
-.icon32.reports--income-statement { background-position: -2688px 0px; }
-.icon32.reports { background-position: -2720px 0px; }
-.icon32.reports--ustva { background-position: -2752px 0px; }
-.icon32.system { background-position: -2784px 0px; }
-.icon32.warehouse--produce-assembly { background-position: -2816px 0px; }
+.icon32.admin { background-position: -0px 0px; }
+.icon32.ap { background-position: -32px 0px; }
+.icon32.ap_aging { background-position: -64px 0px; }
+.icon32.ap_report { background-position: -96px 0px; }
+.icon32.ap_transaction_add { background-position: -128px 0px; }
+.icon32.appointment { background-position: -160px 0px; }
+.icon32.ar { background-position: -192px 0px; }
+.icon32.ar_aging { background-position: -224px 0px; }
+.icon32.ar_report { background-position: -256px 0px; }
+.icon32.ar_transaction_add { background-position: -288px 0px; }
+.icon32.assembly_add { background-position: -320px 0px; }
+.icon32.assembly_produce { background-position: -352px 0px; }
+.icon32.assembly_report { background-position: -384px 0px; }
+.icon32.balance_sheet { background-position: -416px 0px; }
+.icon32.cash { background-position: -448px 0px; }
+.icon32.cash_report { background-position: -480px 0px; }
+.icon32.chart_of_accounts { background-position: -512px 0px; }
+.icon32.contact { background-position: -544px 0px; }
+.icon32.crm { background-position: -576px 0px; }
+.icon32.customer { background-position: -608px 0px; }
+.icon32.customer_add { background-position: -640px 0px; }
+.icon32.customer_report { background-position: -672px 0px; }
+.icon32.datev { background-position: -704px 0px; }
+.icon32.document_template { background-position: -736px 0px; }
+.icon32.dunning_add { background-position: -768px 0px; }
+.icon32.dunnings_report { background-position: -800px 0px; }
+.icon32.email { background-position: -832px 0px; }
+.icon32.follow_up { background-position: -864px 0px; }
+.icon32.gl { background-position: -896px 0px; }
+.icon32.gl_report { background-position: -928px 0px; }
+.icon32.help { background-position: -960px 0px; }
+.icon32.income_statement { background-position: -992px 0px; }
+.icon32.invoices_report { background-position: -1024px 0px; }
+.icon32.journal { background-position: -1056px 0px; }
+.icon32.knowledge { background-position: -1088px 0px; }
+.icon32.label { background-position: -1120px 0px; }
+.icon32.license_add { background-position: -1152px 0px; }
+.icon32.license_report { background-position: -1184px 0px; }
+.icon32.logout { background-position: -1216px 0px; }
+.icon32.master_data { background-position: -1248px 0px; }
+.icon32.master_data_report { background-position: -1280px 0px; }
+.icon32.memo { background-position: -1312px 0px; }
+.icon32.message { background-position: -1344px 0px; }
+.icon32.opportunity { background-position: -1376px 0px; }
+.icon32.package_lists { background-position: -1408px 0px; }
+.icon32.part_add { background-position: -1440px 0px; }
+.icon32.part_report { background-position: -1472px 0px; }
+.icon32.payment { background-position: -1504px 0px; }
+.icon32.payment_report { background-position: -1536px 0px; }
+.icon32.preferences { background-position: -1568px 0px; }
+.icon32.printing { background-position: -1600px 0px; }
+.icon32.program { background-position: -1632px 0px; }
+.icon32.project_add { background-position: -1664px 0px; }
+.icon32.project_report { background-position: -1696px 0px; }
+.icon32.project_transaction_report { background-position: -1728px 0px; }
+.icon32.purchase_order_add { background-position: -1760px 0px; }
+.icon32.purchase_order_printing { background-position: -1792px 0px; }
+.icon32.purchase_order_report { background-position: -1824px 0px; }
+.icon32.quotation_add { background-position: -1856px 0px; }
+.icon32.quotation_printing { background-position: -1888px 0px; }
+.icon32.receipt { background-position: -1920px 0px; }
+.icon32.receipt_printing { background-position: -1952px 0px; }
+.icon32.receipt_report { background-position: -1984px 0px; }
+.icon32.reconcilliation { background-position: -2016px 0px; }
+.icon32.report { background-position: -2048px 0px; }
+.icon32.report_quotations { background-position: -2080px 0px; }
+.icon32.report_sales_orders { background-position: -2112px 0px; }
+.icon32.rfq_add { background-position: -2144px 0px; }
+.icon32.rfq_printing { background-position: -2176px 0px; }
+.icon32.rfq_report { background-position: -2208px 0px; }
+.icon32.sales_invoice_add { background-position: -2240px 0px; }
+.icon32.sales_invoice_printing { background-position: -2272px 0px; }
+.icon32.sales_order_add { background-position: -2304px 0px; }
+.icon32.sales_order_printing { background-position: -2336px 0px; }
+.icon32.search { background-position: -2368px 0px; }
+.icon32.service { background-position: -2400px 0px; }
+.icon32.service_add { background-position: -2432px 0px; }
+.icon32.service_report { background-position: -2464px 0px; }
+.icon32.status { background-position: -2496px 0px; }
+.icon32.system { background-position: -2528px 0px; }
+.icon32.transaction_add { background-position: -2560px 0px; }
+.icon32.user { background-position: -2592px 0px; }
+.icon32.user_group { background-position: -2624px 0px; }
+.icon32.ustva { background-position: -2656px 0px; }
+.icon32.vendor { background-position: -2688px 0px; }
+.icon32.vendor_add { background-position: -2720px 0px; }
+.icon32.vendor_report { background-position: -2752px 0px; }
+.icon32.version { background-position: -2784px 0px; }
+.icon32.window_new { background-position: -2816px 0px; }
--- /dev/null
+.tooltipster-light {
+ border-radius: 5px;
+ border: 1px solid #cccccc;
+ background: #ededed;
+ color: #666666;
+}
+.tooltipster-light .tooltipster-content {
+ font-family: Arial, sans-serif;
+ font-size: 14px;
+ line-height: 16px;
+ padding: 8px 10px;
+}
\ No newline at end of file
--- /dev/null
+.tooltipster-noir {
+ border-radius: 0px;
+ border: 3px solid #2c2c2c;
+ background: #fff;
+ color: #2c2c2c;
+}
+.tooltipster-noir .tooltipster-content {
+ font-family: 'Georgia', serif;
+ font-size: 14px;
+ line-height: 16px;
+ padding: 8px 10px;
+}
\ No newline at end of file
--- /dev/null
+.tooltipster-punk {
+ border-radius: 5px;
+ border-bottom: 3px solid #f71169;
+ background: #2a2a2a;
+ color: #fff;
+}
+.tooltipster-punk .tooltipster-content {
+ font-family: 'Courier', monospace;
+ font-size: 14px;
+ line-height: 16px;
+ padding: 8px 10px;
+}
\ No newline at end of file
--- /dev/null
+.tooltipster-shadow {
+ border-radius: 5px;
+ background: #fff;
+ box-shadow: 0px 0px 14px rgba(0,0,0,0.3);
+ color: #2c2c2c;
+}
+.tooltipster-shadow .tooltipster-content {
+ font-family: 'Arial', sans-serif;
+ font-size: 14px;
+ line-height: 16px;
+ padding: 8px 10px;
+}
\ No newline at end of file
--- /dev/null
+/* This is the default Tooltipster theme (feel free to modify or duplicate and create multiple themes!): */
+.tooltipster-default {
+ border-radius: 5px;
+ border: 2px solid #000;
+ background: #4c4c4c;
+ color: #fff;
+}
+
+/* Use this next selector to style things like font-size and line-height: */
+.tooltipster-default .tooltipster-content {
+ font-family: Arial, sans-serif;
+ font-size: 14px;
+ line-height: 16px;
+ padding: 8px 10px;
+ overflow: hidden;
+}
+
+/* This next selector defines the color of the border on the outside of the arrow. This will automatically match the color and size of the border set on the main tooltip styles. Set display: none; if you would like a border around the tooltip but no border around the arrow */
+.tooltipster-default .tooltipster-arrow .tooltipster-arrow-border {
+ /* border-color: ... !important; */
+}
+
+
+/* If you're using the icon option, use this next selector to style them */
+.tooltipster-icon {
+ cursor: help;
+ margin-left: 4px;
+}
+
+
+
+
+
+
+
+
+/* This is the base styling required to make all Tooltipsters work */
+.tooltipster-base {
+ padding: 0;
+ font-size: 0;
+ line-height: 0;
+ position: absolute;
+ left: 0;
+ top: 0;
+ z-index: 9999999;
+ pointer-events: none;
+ width: auto;
+ overflow: visible;
+}
+.tooltipster-base .tooltipster-content {
+ overflow: hidden;
+}
+
+
+/* These next classes handle the styles for the little arrow attached to the tooltip. By default, the arrow will inherit the same colors and border as what is set on the main tooltip itself. */
+.tooltipster-arrow {
+ display: block;
+ text-align: center;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: -1;
+}
+.tooltipster-arrow span, .tooltipster-arrow-border {
+ display: block;
+ width: 0;
+ height: 0;
+ position: absolute;
+}
+.tooltipster-arrow-top span, .tooltipster-arrow-top-right span, .tooltipster-arrow-top-left span {
+ border-left: 8px solid transparent !important;
+ border-right: 8px solid transparent !important;
+ border-top: 8px solid;
+ bottom: -7px;
+}
+.tooltipster-arrow-top .tooltipster-arrow-border, .tooltipster-arrow-top-right .tooltipster-arrow-border, .tooltipster-arrow-top-left .tooltipster-arrow-border {
+ border-left: 9px solid transparent !important;
+ border-right: 9px solid transparent !important;
+ border-top: 9px solid;
+ bottom: -7px;
+}
+
+.tooltipster-arrow-bottom span, .tooltipster-arrow-bottom-right span, .tooltipster-arrow-bottom-left span {
+ border-left: 8px solid transparent !important;
+ border-right: 8px solid transparent !important;
+ border-bottom: 8px solid;
+ top: -7px;
+}
+.tooltipster-arrow-bottom .tooltipster-arrow-border, .tooltipster-arrow-bottom-right .tooltipster-arrow-border, .tooltipster-arrow-bottom-left .tooltipster-arrow-border {
+ border-left: 9px solid transparent !important;
+ border-right: 9px solid transparent !important;
+ border-bottom: 9px solid;
+ top: -7px;
+}
+.tooltipster-arrow-top span, .tooltipster-arrow-top .tooltipster-arrow-border, .tooltipster-arrow-bottom span, .tooltipster-arrow-bottom .tooltipster-arrow-border {
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+}
+.tooltipster-arrow-top-left span, .tooltipster-arrow-bottom-left span {
+ left: 6px;
+}
+.tooltipster-arrow-top-left .tooltipster-arrow-border, .tooltipster-arrow-bottom-left .tooltipster-arrow-border {
+ left: 5px;
+}
+.tooltipster-arrow-top-right span, .tooltipster-arrow-bottom-right span {
+ right: 6px;
+}
+.tooltipster-arrow-top-right .tooltipster-arrow-border, .tooltipster-arrow-bottom-right .tooltipster-arrow-border {
+ right: 5px;
+}
+.tooltipster-arrow-left span, .tooltipster-arrow-left .tooltipster-arrow-border {
+ border-top: 8px solid transparent !important;
+ border-bottom: 8px solid transparent !important;
+ border-left: 8px solid;
+ top: 50%;
+ margin-top: -7px;
+ right: -7px;
+}
+.tooltipster-arrow-left .tooltipster-arrow-border {
+ border-top: 9px solid transparent !important;
+ border-bottom: 9px solid transparent !important;
+ border-left: 9px solid;
+ margin-top: -8px;
+}
+.tooltipster-arrow-right span, .tooltipster-arrow-right .tooltipster-arrow-border {
+ border-top: 8px solid transparent !important;
+ border-bottom: 8px solid transparent !important;
+ border-right: 8px solid;
+ top: 50%;
+ margin-top: -7px;
+ left: -7px;
+}
+.tooltipster-arrow-right .tooltipster-arrow-border {
+ border-top: 9px solid transparent !important;
+ border-bottom: 9px solid transparent !important;
+ border-right: 9px solid;
+ margin-top: -8px;
+}
+
+
+/* Some CSS magic for the awesome animations - feel free to make your own custom animations and reference it in your Tooltipster settings! */
+
+.tooltipster-fade {
+ opacity: 0;
+ -webkit-transition-property: opacity;
+ -moz-transition-property: opacity;
+ -o-transition-property: opacity;
+ -ms-transition-property: opacity;
+ transition-property: opacity;
+}
+.tooltipster-fade-show {
+ opacity: 1;
+}
+
+.tooltipster-grow {
+ -webkit-transform: scale(0,0);
+ -moz-transform: scale(0,0);
+ -o-transform: scale(0,0);
+ -ms-transform: scale(0,0);
+ transform: scale(0,0);
+ -webkit-transition-property: -webkit-transform;
+ -moz-transition-property: -moz-transform;
+ -o-transition-property: -o-transform;
+ -ms-transition-property: -ms-transform;
+ transition-property: transform;
+ -webkit-backface-visibility: hidden;
+}
+.tooltipster-grow-show {
+ -webkit-transform: scale(1,1);
+ -moz-transform: scale(1,1);
+ -o-transform: scale(1,1);
+ -ms-transform: scale(1,1);
+ transform: scale(1,1);
+ -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+}
+
+.tooltipster-swing {
+ opacity: 0;
+ -webkit-transform: rotateZ(4deg);
+ -moz-transform: rotateZ(4deg);
+ -o-transform: rotateZ(4deg);
+ -ms-transform: rotateZ(4deg);
+ transform: rotateZ(4deg);
+ -webkit-transition-property: -webkit-transform, opacity;
+ -moz-transition-property: -moz-transform;
+ -o-transition-property: -o-transform;
+ -ms-transition-property: -ms-transform;
+ transition-property: transform;
+}
+.tooltipster-swing-show {
+ opacity: 1;
+ -webkit-transform: rotateZ(0deg);
+ -moz-transform: rotateZ(0deg);
+ -o-transform: rotateZ(0deg);
+ -ms-transform: rotateZ(0deg);
+ transform: rotateZ(0deg);
+ -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 1);
+ -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4);
+ -moz-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4);
+ -ms-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4);
+ -o-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4);
+ transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4);
+}
+
+.tooltipster-fall {
+ top: 0;
+ -webkit-transition-property: top;
+ -moz-transition-property: top;
+ -o-transition-property: top;
+ -ms-transition-property: top;
+ transition-property: top;
+ -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+}
+.tooltipster-fall-show {
+}
+.tooltipster-fall.tooltipster-dying {
+ -webkit-transition-property: all;
+ -moz-transition-property: all;
+ -o-transition-property: all;
+ -ms-transition-property: all;
+ transition-property: all;
+ top: 0px !important;
+ opacity: 0;
+}
+
+.tooltipster-slide {
+ left: -40px;
+ -webkit-transition-property: left;
+ -moz-transition-property: left;
+ -o-transition-property: left;
+ -ms-transition-property: left;
+ transition-property: left;
+ -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+ transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15);
+}
+.tooltipster-slide.tooltipster-slide-show {
+}
+.tooltipster-slide.tooltipster-dying {
+ -webkit-transition-property: all;
+ -moz-transition-property: all;
+ -o-transition-property: all;
+ -ms-transition-property: all;
+ transition-property: all;
+ left: 0px !important;
+ opacity: 0;
+}
+
+
+/* CSS transition for when contenting is changing in a tooltip that is still open. The only properties that will NOT transition are: width, height, top, and left */
+.tooltipster-content-changing {
+ opacity: 0.5;
+ -webkit-transform: scale(1.1, 1.1);
+ -moz-transform: scale(1.1, 1.1);
+ -o-transform: scale(1.1, 1.1);
+ -ms-transform: scale(1.1, 1.1);
+ transform: scale(1.1, 1.1);
+}
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>cusordnumber_oe</varname></term>
+
+ <listitem>
+ <para>Bestellnummer des Kunden aus dem Auftrag, aus dem der Posten ursprünglich stammt (nur Verkauf)</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>discount</varname></term>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>donumber_do</varname></term>
+
+ <listitem>
+ <para>Lieferscheinnummer des Lieferscheins, aus dem die Position ursprünglich stammt, wenn die Rechnung im Rahmen des Workflows aus einem Lieferschein erstellt wurde.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>drawing</varname></term>
<term><varname>ordnumber_oe</varname></term>
<listitem>
- <para>Auftragsnummer des Originalauftrags, wenn die Rechnung
- aus einem Sammelauftrag erstellt wurde</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>donumber_do</varname></term>
-
- <listitem>
- <para>Lieferscheinnummer desjenigen Lieferscheins, aus dem die Position stammt, sofern die Rechnung aus einem oder
- mehreren Lieferscheinen erstellt wurde</para>
+ <para>Auftragsnummer des Originalauftrags, aus dem der Posten ursprünglich stammt. Nützlich, wenn die Rechnung aus mehreren Lieferscheinen zusammengefasst wurde, oder wenn zwischendurch eine Sammelauftrag aus mehreren Aufträgen erstellt wurde. In letzterem Fall wird die unsprüngliche Auftragsnummer angezeigt.</para>
</listitem>
</varlistentry>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>transdate_do</varname></term>
+
+ <listitem>
+ <para>Datum des Lieferscheins, wenn die Rechnung im Rahmen des Workflows aus einem Lieferschein stammte.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>transdate_oe</varname></term>
<listitem>
- <para>Auftragsdatum des Originalauftrags, wenn die Rechnung
- aus einem Sammelauftrag erstellt wurde</para>
+ <para>Datum des Auftrags, wenn die Rechnung im Rahmen des Workflows aus einem Auftrag erstellt wurde. Wenn es Sammelaufträge gab wird das Datum des ursprünglichen Auftrags genommen.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>transdate_quo</varname></term>
+
+ <listitem>
+ <para>Datum des Angebots, wenn die Position im Rahmen des Workflows aus einem Angebot stammte.</para>
</listitem>
</varlistentry>
+++ /dev/null
-MDI-Text-Editor-16x16.png
\ No newline at end of file
+++ /dev/null
-MDI-Text-Editor-16x16.png
\ No newline at end of file
+++ /dev/null
-phone.png
\ No newline at end of file
--- /dev/null
+mdi_text_editor.png
\ No newline at end of file
--- /dev/null
+mdi_text_editor.png
\ No newline at end of file
var picker = $('<div>');
$dummy.after(pcont);
pcont.append(picker);
- picker.addClass('icon16 crm--search').click(open_dialog);
+ picker.addClass('icon16 search').click(open_dialog);
var pp = {
real: function() { return $real },
--- /dev/null
+/* Tooltipster v3.3.0 */;(function(e,t,n){function s(t,n){this.bodyOverflowX;this.callbacks={hide:[],show:[]};this.checkInterval=null;this.Content;this.$el=e(t);this.$elProxy;this.elProxyPosition;this.enabled=true;this.options=e.extend({},i,n);this.mouseIsOverProxy=false;this.namespace="tooltipster-"+Math.round(Math.random()*1e5);this.Status="hidden";this.timerHide=null;this.timerShow=null;this.$tooltip;this.options.iconTheme=this.options.iconTheme.replace(".","");this.options.theme=this.options.theme.replace(".","");this._init()}function o(t,n){var r=true;e.each(t,function(e,i){if(typeof n[e]==="undefined"||t[e]!==n[e]){r=false;return false}});return r}function f(){return!a&&u}function l(){var e=n.body||n.documentElement,t=e.style,r="transition";if(typeof t[r]=="string"){return true}v=["Moz","Webkit","Khtml","O","ms"],r=r.charAt(0).toUpperCase()+r.substr(1);for(var i=0;i<v.length;i++){if(typeof t[v[i]+r]=="string"){return true}}return false}var r="tooltipster",i={animation:"fade",arrow:true,arrowColor:"",autoClose:true,content:null,contentAsHTML:false,contentCloning:true,debug:true,delay:200,minWidth:0,maxWidth:null,functionInit:function(e,t){},functionBefore:function(e,t){t()},functionReady:function(e,t){},functionAfter:function(e){},hideOnClick:false,icon:"(?)",iconCloning:true,iconDesktop:false,iconTouch:false,iconTheme:"tooltipster-icon",interactive:false,interactiveTolerance:350,multiple:false,offsetX:0,offsetY:0,onlyOne:false,position:"top",positionTracker:false,positionTrackerCallback:function(e){if(this.option("trigger")=="hover"&&this.option("autoClose")){this.hide()}},restoration:"current",speed:350,timer:0,theme:"tooltipster-default",touchDevices:true,trigger:"hover",updateAnimation:true};s.prototype={_init:function(){var t=this;if(n.querySelector){var r=null;if(t.$el.data("tooltipster-initialTitle")===undefined){r=t.$el.attr("title");if(r===undefined)r=null;t.$el.data("tooltipster-initialTitle",r)}if(t.options.content!==null){t._content_set(t.options.content)}else{t._content_set(r)}var i=t.options.functionInit.call(t.$el,t.$el,t.Content);if(typeof i!=="undefined")t._content_set(i);t.$el.removeAttr("title").addClass("tooltipstered");if(!u&&t.options.iconDesktop||u&&t.options.iconTouch){if(typeof t.options.icon==="string"){t.$elProxy=e('<span class="'+t.options.iconTheme+'"></span>');t.$elProxy.text(t.options.icon)}else{if(t.options.iconCloning)t.$elProxy=t.options.icon.clone(true);else t.$elProxy=t.options.icon}t.$elProxy.insertAfter(t.$el)}else{t.$elProxy=t.$el}if(t.options.trigger=="hover"){t.$elProxy.on("mouseenter."+t.namespace,function(){if(!f()||t.options.touchDevices){t.mouseIsOverProxy=true;t._show()}}).on("mouseleave."+t.namespace,function(){if(!f()||t.options.touchDevices){t.mouseIsOverProxy=false}});if(u&&t.options.touchDevices){t.$elProxy.on("touchstart."+t.namespace,function(){t._showNow()})}}else if(t.options.trigger=="click"){t.$elProxy.on("click."+t.namespace,function(){if(!f()||t.options.touchDevices){t._show()}})}}},_show:function(){var e=this;if(e.Status!="shown"&&e.Status!="appearing"){if(e.options.delay){e.timerShow=setTimeout(function(){if(e.options.trigger=="click"||e.options.trigger=="hover"&&e.mouseIsOverProxy){e._showNow()}},e.options.delay)}else e._showNow()}},_showNow:function(n){var r=this;r.options.functionBefore.call(r.$el,r.$el,function(){if(r.enabled&&r.Content!==null){if(n)r.callbacks.show.push(n);r.callbacks.hide=[];clearTimeout(r.timerShow);r.timerShow=null;clearTimeout(r.timerHide);r.timerHide=null;if(r.options.onlyOne){e(".tooltipstered").not(r.$el).each(function(t,n){var r=e(n),i=r.data("tooltipster-ns");e.each(i,function(e,t){var n=r.data(t),i=n.status(),s=n.option("autoClose");if(i!=="hidden"&&i!=="disappearing"&&s){n.hide()}})})}var i=function(){r.Status="shown";e.each(r.callbacks.show,function(e,t){t.call(r.$el)});r.callbacks.show=[]};if(r.Status!=="hidden"){var s=0;if(r.Status==="disappearing"){r.Status="appearing";if(l()){r.$tooltip.clearQueue().removeClass("tooltipster-dying").addClass("tooltipster-"+r.options.animation+"-show");if(r.options.speed>0)r.$tooltip.delay(r.options.speed);r.$tooltip.queue(i)}else{r.$tooltip.stop().fadeIn(i)}}else if(r.Status==="shown"){i()}}else{r.Status="appearing";var s=r.options.speed;r.bodyOverflowX=e("body").css("overflow-x");e("body").css("overflow-x","hidden");var o="tooltipster-"+r.options.animation,a="-webkit-transition-duration: "+r.options.speed+"ms; -webkit-animation-duration: "+r.options.speed+"ms; -moz-transition-duration: "+r.options.speed+"ms; -moz-animation-duration: "+r.options.speed+"ms; -o-transition-duration: "+r.options.speed+"ms; -o-animation-duration: "+r.options.speed+"ms; -ms-transition-duration: "+r.options.speed+"ms; -ms-animation-duration: "+r.options.speed+"ms; transition-duration: "+r.options.speed+"ms; animation-duration: "+r.options.speed+"ms;",f=r.options.minWidth?"min-width:"+Math.round(r.options.minWidth)+"px;":"",c=r.options.maxWidth?"max-width:"+Math.round(r.options.maxWidth)+"px;":"",h=r.options.interactive?"pointer-events: auto;":"";r.$tooltip=e('<div class="tooltipster-base '+r.options.theme+'" style="'+f+" "+c+" "+h+" "+a+'"><div class="tooltipster-content"></div></div>');if(l())r.$tooltip.addClass(o);r._content_insert();r.$tooltip.appendTo("body");r.reposition();r.options.functionReady.call(r.$el,r.$el,r.$tooltip);if(l()){r.$tooltip.addClass(o+"-show");if(r.options.speed>0)r.$tooltip.delay(r.options.speed);r.$tooltip.queue(i)}else{r.$tooltip.css("display","none").fadeIn(r.options.speed,i)}r._interval_set();e(t).on("scroll."+r.namespace+" resize."+r.namespace,function(){r.reposition()});if(r.options.autoClose){e("body").off("."+r.namespace);if(r.options.trigger=="hover"){if(u){setTimeout(function(){e("body").on("touchstart."+r.namespace,function(){r.hide()})},0)}if(r.options.interactive){if(u){r.$tooltip.on("touchstart."+r.namespace,function(e){e.stopPropagation()})}var p=null;r.$elProxy.add(r.$tooltip).on("mouseleave."+r.namespace+"-autoClose",function(){clearTimeout(p);p=setTimeout(function(){r.hide()},r.options.interactiveTolerance)}).on("mouseenter."+r.namespace+"-autoClose",function(){clearTimeout(p)})}else{r.$elProxy.on("mouseleave."+r.namespace+"-autoClose",function(){r.hide()})}if(r.options.hideOnClick){r.$elProxy.on("click."+r.namespace+"-autoClose",function(){r.hide()})}}else if(r.options.trigger=="click"){setTimeout(function(){e("body").on("click."+r.namespace+" touchstart."+r.namespace,function(){r.hide()})},0);if(r.options.interactive){r.$tooltip.on("click."+r.namespace+" touchstart."+r.namespace,function(e){e.stopPropagation()})}}}}if(r.options.timer>0){r.timerHide=setTimeout(function(){r.timerHide=null;r.hide()},r.options.timer+s)}}})},_interval_set:function(){var t=this;t.checkInterval=setInterval(function(){if(e("body").find(t.$el).length===0||e("body").find(t.$elProxy).length===0||t.Status=="hidden"||e("body").find(t.$tooltip).length===0){if(t.Status=="shown"||t.Status=="appearing")t.hide();t._interval_cancel()}else{if(t.options.positionTracker){var n=t._repositionInfo(t.$elProxy),r=false;if(o(n.dimension,t.elProxyPosition.dimension)){if(t.$elProxy.css("position")==="fixed"){if(o(n.position,t.elProxyPosition.position))r=true}else{if(o(n.offset,t.elProxyPosition.offset))r=true}}if(!r){t.reposition();t.options.positionTrackerCallback.call(t,t.$el)}}}},200)},_interval_cancel:function(){clearInterval(this.checkInterval);this.checkInterval=null},_content_set:function(e){if(typeof e==="object"&&e!==null&&this.options.contentCloning){e=e.clone(true)}this.Content=e},_content_insert:function(){var e=this,t=this.$tooltip.find(".tooltipster-content");if(typeof e.Content==="string"&&!e.options.contentAsHTML){t.text(e.Content)}else{t.empty().append(e.Content)}},_update:function(e){var t=this;t._content_set(e);if(t.Content!==null){if(t.Status!=="hidden"){t._content_insert();t.reposition();if(t.options.updateAnimation){if(l()){t.$tooltip.css({width:"","-webkit-transition":"all "+t.options.speed+"ms, width 0ms, height 0ms, left 0ms, top 0ms","-moz-transition":"all "+t.options.speed+"ms, width 0ms, height 0ms, left 0ms, top 0ms","-o-transition":"all "+t.options.speed+"ms, width 0ms, height 0ms, left 0ms, top 0ms","-ms-transition":"all "+t.options.speed+"ms, width 0ms, height 0ms, left 0ms, top 0ms",transition:"all "+t.options.speed+"ms, width 0ms, height 0ms, left 0ms, top 0ms"}).addClass("tooltipster-content-changing");setTimeout(function(){if(t.Status!="hidden"){t.$tooltip.removeClass("tooltipster-content-changing");setTimeout(function(){if(t.Status!=="hidden"){t.$tooltip.css({"-webkit-transition":t.options.speed+"ms","-moz-transition":t.options.speed+"ms","-o-transition":t.options.speed+"ms","-ms-transition":t.options.speed+"ms",transition:t.options.speed+"ms"})}},t.options.speed)}},t.options.speed)}else{t.$tooltip.fadeTo(t.options.speed,.5,function(){if(t.Status!="hidden"){t.$tooltip.fadeTo(t.options.speed,1)}})}}}}else{t.hide()}},_repositionInfo:function(e){return{dimension:{height:e.outerHeight(false),width:e.outerWidth(false)},offset:e.offset(),position:{left:parseInt(e.css("left")),top:parseInt(e.css("top"))}}},hide:function(n){var r=this;if(n)r.callbacks.hide.push(n);r.callbacks.show=[];clearTimeout(r.timerShow);r.timerShow=null;clearTimeout(r.timerHide);r.timerHide=null;var i=function(){e.each(r.callbacks.hide,function(e,t){t.call(r.$el)});r.callbacks.hide=[]};if(r.Status=="shown"||r.Status=="appearing"){r.Status="disappearing";var s=function(){r.Status="hidden";if(typeof r.Content=="object"&&r.Content!==null){r.Content.detach()}r.$tooltip.remove();r.$tooltip=null;e(t).off("."+r.namespace);e("body").off("."+r.namespace).css("overflow-x",r.bodyOverflowX);e("body").off("."+r.namespace);r.$elProxy.off("."+r.namespace+"-autoClose");r.options.functionAfter.call(r.$el,r.$el);i()};if(l()){r.$tooltip.clearQueue().removeClass("tooltipster-"+r.options.animation+"-show").addClass("tooltipster-dying");if(r.options.speed>0)r.$tooltip.delay(r.options.speed);r.$tooltip.queue(s)}else{r.$tooltip.stop().fadeOut(r.options.speed,s)}}else if(r.Status=="hidden"){i()}return r},show:function(e){this._showNow(e);return this},update:function(e){return this.content(e)},content:function(e){if(typeof e==="undefined"){return this.Content}else{this._update(e);return this}},reposition:function(){var n=this;if(e("body").find(n.$tooltip).length!==0){n.$tooltip.css("width","");n.elProxyPosition=n._repositionInfo(n.$elProxy);var r=null,i=e(t).width(),s=n.elProxyPosition,o=n.$tooltip.outerWidth(false),u=n.$tooltip.innerWidth()+1,a=n.$tooltip.outerHeight(false);if(n.$elProxy.is("area")){var f=n.$elProxy.attr("shape"),l=n.$elProxy.parent().attr("name"),c=e('img[usemap="#'+l+'"]'),h=c.offset().left,p=c.offset().top,d=n.$elProxy.attr("coords")!==undefined?n.$elProxy.attr("coords").split(","):undefined;if(f=="circle"){var v=parseInt(d[0]),m=parseInt(d[1]),g=parseInt(d[2]);s.dimension.height=g*2;s.dimension.width=g*2;s.offset.top=p+m-g;s.offset.left=h+v-g}else if(f=="rect"){var v=parseInt(d[0]),m=parseInt(d[1]),y=parseInt(d[2]),b=parseInt(d[3]);s.dimension.height=b-m;s.dimension.width=y-v;s.offset.top=p+m;s.offset.left=h+v}else if(f=="poly"){var w=[],E=[],S=0,x=0,T=0,N=0,C="even";for(var k=0;k<d.length;k++){var L=parseInt(d[k]);if(C=="even"){if(L>T){T=L;if(k===0){S=T}}if(L<S){S=L}C="odd"}else{if(L>N){N=L;if(k==1){x=N}}if(L<x){x=L}C="even"}}s.dimension.height=N-x;s.dimension.width=T-S;s.offset.top=p+x;s.offset.left=h+S}else{s.dimension.height=c.outerHeight(false);s.dimension.width=c.outerWidth(false);s.offset.top=p;s.offset.left=h}}var A=0,O=0,M=0,_=parseInt(n.options.offsetY),D=parseInt(n.options.offsetX),P=n.options.position;function H(){var n=e(t).scrollLeft();if(A-n<0){r=A-n;A=n}if(A+o-n>i){r=A-(i+n-o);A=i+n-o}}function B(n,r){if(s.offset.top-e(t).scrollTop()-a-_-12<0&&r.indexOf("top")>-1){P=n}if(s.offset.top+s.dimension.height+a+12+_>e(t).scrollTop()+e(t).height()&&r.indexOf("bottom")>-1){P=n;M=s.offset.top-a-_-12}}if(P=="top"){var j=s.offset.left+o-(s.offset.left+s.dimension.width);A=s.offset.left+D-j/2;M=s.offset.top-a-_-12;H();B("bottom","top")}if(P=="top-left"){A=s.offset.left+D;M=s.offset.top-a-_-12;H();B("bottom-left","top-left")}if(P=="top-right"){A=s.offset.left+s.dimension.width+D-o;M=s.offset.top-a-_-12;H();B("bottom-right","top-right")}if(P=="bottom"){var j=s.offset.left+o-(s.offset.left+s.dimension.width);A=s.offset.left-j/2+D;M=s.offset.top+s.dimension.height+_+12;H();B("top","bottom")}if(P=="bottom-left"){A=s.offset.left+D;M=s.offset.top+s.dimension.height+_+12;H();B("top-left","bottom-left")}if(P=="bottom-right"){A=s.offset.left+s.dimension.width+D-o;M=s.offset.top+s.dimension.height+_+12;H();B("top-right","bottom-right")}if(P=="left"){A=s.offset.left-D-o-12;O=s.offset.left+D+s.dimension.width+12;var F=s.offset.top+a-(s.offset.top+s.dimension.height);M=s.offset.top-F/2-_;if(A<0&&O+o>i){var I=parseFloat(n.$tooltip.css("border-width"))*2,q=o+A-I;n.$tooltip.css("width",q+"px");a=n.$tooltip.outerHeight(false);A=s.offset.left-D-q-12-I;F=s.offset.top+a-(s.offset.top+s.dimension.height);M=s.offset.top-F/2-_}else if(A<0){A=s.offset.left+D+s.dimension.width+12;r="left"}}if(P=="right"){A=s.offset.left+D+s.dimension.width+12;O=s.offset.left-D-o-12;var F=s.offset.top+a-(s.offset.top+s.dimension.height);M=s.offset.top-F/2-_;if(A+o>i&&O<0){var I=parseFloat(n.$tooltip.css("border-width"))*2,q=i-A-I;n.$tooltip.css("width",q+"px");a=n.$tooltip.outerHeight(false);F=s.offset.top+a-(s.offset.top+s.dimension.height);M=s.offset.top-F/2-_}else if(A+o>i){A=s.offset.left-D-o-12;r="right"}}if(n.options.arrow){var R="tooltipster-arrow-"+P;if(n.options.arrowColor.length<1){var U=n.$tooltip.css("background-color")}else{var U=n.options.arrowColor}if(!r){r=""}else if(r=="left"){R="tooltipster-arrow-right";r=""}else if(r=="right"){R="tooltipster-arrow-left";r=""}else{r="left:"+Math.round(r)+"px;"}if(P=="top"||P=="top-left"||P=="top-right"){var z=parseFloat(n.$tooltip.css("border-bottom-width")),W=n.$tooltip.css("border-bottom-color")}else if(P=="bottom"||P=="bottom-left"||P=="bottom-right"){var z=parseFloat(n.$tooltip.css("border-top-width")),W=n.$tooltip.css("border-top-color")}else if(P=="left"){var z=parseFloat(n.$tooltip.css("border-right-width")),W=n.$tooltip.css("border-right-color")}else if(P=="right"){var z=parseFloat(n.$tooltip.css("border-left-width")),W=n.$tooltip.css("border-left-color")}else{var z=parseFloat(n.$tooltip.css("border-bottom-width")),W=n.$tooltip.css("border-bottom-color")}if(z>1){z++}var X="";if(z!==0){var V="",J="border-color: "+W+";";if(R.indexOf("bottom")!==-1){V="margin-top: -"+Math.round(z)+"px;"}else if(R.indexOf("top")!==-1){V="margin-bottom: -"+Math.round(z)+"px;"}else if(R.indexOf("left")!==-1){V="margin-right: -"+Math.round(z)+"px;"}else if(R.indexOf("right")!==-1){V="margin-left: -"+Math.round(z)+"px;"}X='<span class="tooltipster-arrow-border" style="'+V+" "+J+';"></span>'}n.$tooltip.find(".tooltipster-arrow").remove();var K='<div class="'+R+' tooltipster-arrow" style="'+r+'">'+X+'<span style="border-color:'+U+';"></span></div>';n.$tooltip.append(K)}n.$tooltip.css({top:Math.round(M)+"px",left:Math.round(A)+"px"})}return n},enable:function(){this.enabled=true;return this},disable:function(){this.hide();this.enabled=false;return this},destroy:function(){var t=this;t.hide();if(t.$el[0]!==t.$elProxy[0]){t.$elProxy.remove()}t.$el.removeData(t.namespace).off("."+t.namespace);var n=t.$el.data("tooltipster-ns");if(n.length===1){var r=null;if(t.options.restoration==="previous"){r=t.$el.data("tooltipster-initialTitle")}else if(t.options.restoration==="current"){r=typeof t.Content==="string"?t.Content:e("<div></div>").append(t.Content).html()}if(r){t.$el.attr("title",r)}t.$el.removeClass("tooltipstered").removeData("tooltipster-ns").removeData("tooltipster-initialTitle")}else{n=e.grep(n,function(e,n){return e!==t.namespace});t.$el.data("tooltipster-ns",n)}return t},elementIcon:function(){return this.$el[0]!==this.$elProxy[0]?this.$elProxy[0]:undefined},elementTooltip:function(){return this.$tooltip?this.$tooltip[0]:undefined},option:function(e,t){if(typeof t=="undefined")return this.options[e];else{this.options[e]=t;return this}},status:function(){return this.Status}};e.fn[r]=function(){var t=arguments;if(this.length===0){if(typeof t[0]==="string"){var n=true;switch(t[0]){case"setDefaults":e.extend(i,t[1]);break;default:n=false;break}if(n)return true;else return this}else{return this}}else{if(typeof t[0]==="string"){var r="#*$~&";this.each(function(){var n=e(this).data("tooltipster-ns"),i=n?e(this).data(n[0]):null;if(i){if(typeof i[t[0]]==="function"){var s=i[t[0]](t[1],t[2])}else{throw new Error('Unknown method .tooltipster("'+t[0]+'")')}if(s!==i){r=s;return false}}else{throw new Error("You called Tooltipster's \""+t[0]+'" method on an uninitialized element')}});return r!=="#*$~&"?r:this}else{var o=[],u=t[0]&&typeof t[0].multiple!=="undefined",a=u&&t[0].multiple||!u&&i.multiple,f=t[0]&&typeof t[0].debug!=="undefined",l=f&&t[0].debug||!f&&i.debug;this.each(function(){var n=false,r=e(this).data("tooltipster-ns"),i=null;if(!r){n=true}else if(a){n=true}else if(l){console.log('Tooltipster: one or more tooltips are already attached to this element: ignoring. Use the "multiple" option to attach more tooltips.')}if(n){i=new s(this,t[0]);if(!r)r=[];r.push(i.namespace);e(this).data("tooltipster-ns",r);e(this).data(i.namespace,i)}o.push(i)});if(a)return o;else return this}}};var u=!!("ontouchstart"in t);var a=false;e("body").one("mousemove",function(){a=true})})(jQuery,window,document);
\ No newline at end of file
if (func)
func();
- ns.run_once_for('.tooltip', 'tooltip', function(elt) {
- $(elt).tooltip();
+ ns.run_once_for('.tooltipster', 'tooltipster', function(elt) {
+ $(elt).tooltipster({
+ contentAsHTML: false,
+ theme: 'tooltipster-light'
+ })
+ });
+
+ ns.run_once_for('.tooltipster-html', 'tooltipster-html', function(elt) {
+ $(elt).tooltipster({
+ contentAsHTML: true,
+ theme: 'tooltipster-light'
+ })
});
ns.run_once_for('.tabwidget', 'tabwidget', kivi.init_tabwidget);
+++ /dev/null
-/* This notice must be untouched at all times.
-Copyright (c) 2002-2008 Walter Zorn. All rights reserved.
-
-wz_tooltip.js v. 5.31
-
-The latest version is available at
-http://www.walterzorn.com
-or http://www.devira.com
-or http://www.walterzorn.de
-
-Created 1.12.2002 by Walter Zorn (Web: http://www.walterzorn.com )
-Last modified: 7.11.2008
-
-Easy-to-use cross-browser tooltips.
-Just include the script at the beginning of the <body> section, and invoke
-Tip('Tooltip text') to show and UnTip() to hide the tooltip, from the desired
-HTML eventhandlers. Example:
-<a onmouseover="Tip('Some text')" onmouseout="UnTip()" href="index.htm">My home page</a>
-No container DIV required.
-By default, width and height of tooltips are automatically adapted to content.
-Is even capable of dynamically converting arbitrary HTML elements to tooltips
-by calling TagToTip('ID_of_HTML_element_to_be_converted') instead of Tip(),
-which means you can put important, search-engine-relevant stuff into tooltips.
-Appearance & behaviour of tooltips can be individually configured
-via commands passed to Tip() or TagToTip().
-
-Tab Width: 4
-LICENSE: LGPL
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License (LGPL) as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library 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.
-
-For more details on the GNU Lesser General Public License,
-see http://www.gnu.org/copyleft/lesser.html
-*/
-
-var config = new Object();
-
-
-//=================== GLOBAL TOOLTIP CONFIGURATION =========================//
-var tt_Debug = true // false or true - recommended: false once you release your page to the public
-var tt_Enabled = true // Allows to (temporarily) suppress tooltips, e.g. by providing the user with a button that sets this global variable to false
-var TagsToTip = true // false or true - if true, HTML elements to be converted to tooltips via TagToTip() are automatically hidden;
- // if false, you should hide those HTML elements yourself
-
-// For each of the following config variables there exists a command, which is
-// just the variablename in uppercase, to be passed to Tip() or TagToTip() to
-// configure tooltips individually. Individual commands override global
-// configuration. Order of commands is arbitrary.
-// Example: onmouseover="Tip('Tooltip text', LEFT, true, BGCOLOR, '#FF9900', FADEIN, 400)"
-
-config. Above = false // false or true - tooltip above mousepointer
-config. BgColor = '#E2E7FF' // Background colour (HTML colour value, in quotes)
-config. BgImg = '' // Path to background image, none if empty string ''
-config. BorderColor = '#003099'
-config. BorderStyle = 'solid' // Any permitted CSS value, but I recommend 'solid', 'dotted' or 'dashed'
-config. BorderWidth = 1
-config. CenterMouse = false // false or true - center the tip horizontally below (or above) the mousepointer
-config. ClickClose = false // false or true - close tooltip if the user clicks somewhere
-config. ClickSticky = false // false or true - make tooltip sticky if user left-clicks on the hovered element while the tooltip is active
-config. CloseBtn = false // false or true - closebutton in titlebar
-config. CloseBtnColors = ['#990000', '#FFFFFF', '#DD3333', '#FFFFFF'] // [Background, text, hovered background, hovered text] - use empty strings '' to inherit title colours
-config. CloseBtnText = ' X ' // Close button text (may also be an image tag)
-config. CopyContent = true // When converting a HTML element to a tooltip, copy only the element's content, rather than converting the element by its own
-config. Delay = 400 // Time span in ms until tooltip shows up
-config. Duration = 0 // Time span in ms after which the tooltip disappears; 0 for infinite duration, < 0 for delay in ms _after_ the onmouseout until the tooltip disappears
-config. Exclusive = false // false or true - no other tooltip can appear until the current one has actively been closed
-config. FadeIn = 100 // Fade-in duration in ms, e.g. 400; 0 for no animation
-config. FadeOut = 100
-config. FadeInterval = 30 // Duration of each fade step in ms (recommended: 30) - shorter is smoother but causes more CPU-load
-config. Fix = null // Fixated position, two modes. Mode 1: x- an y-coordinates in brackets, e.g. [210, 480]. Mode 2: Show tooltip at a position related to an HTML element: [ID of HTML element, x-offset, y-offset from HTML element], e.g. ['SomeID', 10, 30]. Value null (default) for no fixated positioning.
-config. FollowMouse = true // false or true - tooltip follows the mouse
-config. FontColor = '#000044'
-config. FontFace = 'Verdana,Geneva,sans-serif'
-config. FontSize = '8pt' // E.g. '9pt' or '12px' - unit is mandatory
-config. FontWeight = 'normal' // 'normal' or 'bold';
-config. Height = 0 // Tooltip height; 0 for automatic adaption to tooltip content, < 0 (e.g. -100) for a maximum for automatic adaption
-config. JumpHorz = false // false or true - jump horizontally to other side of mouse if tooltip would extend past clientarea boundary
-config. JumpVert = true // false or true - jump vertically "
-config. Left = false // false or true - tooltip on the left of the mouse
-config. OffsetX = 14 // Horizontal offset of left-top corner from mousepointer
-config. OffsetY = 8 // Vertical offset
-config. Opacity = 100 // Integer between 0 and 100 - opacity of tooltip in percent
-config. Padding = 3 // Spacing between border and content
-config. Shadow = false // false or true
-config. ShadowColor = '#C0C0C0'
-config. ShadowWidth = 5
-config. Sticky = false // false or true - fixate tip, ie. don't follow the mouse and don't hide on mouseout
-config. TextAlign = 'left' // 'left', 'right' or 'justify'
-config. Title = '' // Default title text applied to all tips (no default title: empty string '')
-config. TitleAlign = 'left' // 'left' or 'right' - text alignment inside the title bar
-config. TitleBgColor = '' // If empty string '', BorderColor will be used
-config. TitleFontColor = '#FFFFFF' // Color of title text - if '', BgColor (of tooltip body) will be used
-config. TitleFontFace = '' // If '' use FontFace (boldified)
-config. TitleFontSize = '' // If '' use FontSize
-config. TitlePadding = 2
-config. Width = 0 // Tooltip width; 0 for automatic adaption to tooltip content; < -1 (e.g. -240) for a maximum width for that automatic adaption;
- // -1: tooltip width confined to the width required for the titlebar
-//======= END OF TOOLTIP CONFIG, DO NOT CHANGE ANYTHING BELOW ==============//
-
-
-
-
-//===================== PUBLIC =============================================//
-function Tip()
-{
- tt_Tip(arguments, null);
-}
-function TagToTip()
-{
- var t2t = tt_GetElt(arguments[0]);
- if(t2t)
- tt_Tip(arguments, t2t);
-}
-function UnTip()
-{
- tt_OpReHref();
- if(tt_aV[DURATION] < 0 && (tt_iState & 0x2))
- tt_tDurt.Timer("tt_HideInit()", -tt_aV[DURATION], true);
- else if(!(tt_aV[STICKY] && (tt_iState & 0x2)))
- tt_HideInit();
-}
-
-//================== PUBLIC PLUGIN API =====================================//
-// Extension eventhandlers currently supported:
-// OnLoadConfig, OnCreateContentString, OnSubDivsCreated, OnShow, OnMoveBefore,
-// OnMoveAfter, OnHideInit, OnHide, OnKill
-
-var tt_aElt = new Array(10), // Container DIV, outer title & body DIVs, inner title & body TDs, closebutton SPAN, shadow DIVs, and IFRAME to cover windowed elements in IE
-tt_aV = new Array(), // Caches and enumerates config data for currently active tooltip
-tt_sContent, // Inner tooltip text or HTML
-tt_t2t, tt_t2tDad, // Tag converted to tip, and its DOM parent element
-tt_musX, tt_musY,
-tt_over,
-tt_x, tt_y, tt_w, tt_h; // Position, width and height of currently displayed tooltip
-
-function tt_Extension()
-{
- tt_ExtCmdEnum();
- tt_aExt[tt_aExt.length] = this;
- return this;
-}
-function tt_SetTipPos(x, y)
-{
- var css = tt_aElt[0].style;
-
- tt_x = x;
- tt_y = y;
- css.left = x + "px";
- css.top = y + "px";
- if(tt_ie56)
- {
- var ifrm = tt_aElt[tt_aElt.length - 1];
- if(ifrm)
- {
- ifrm.style.left = css.left;
- ifrm.style.top = css.top;
- }
- }
-}
-function tt_HideInit()
-{
- if(tt_iState)
- {
- tt_ExtCallFncs(0, "HideInit");
- tt_iState &= ~(0x4 | 0x8);
- if(tt_flagOpa && tt_aV[FADEOUT])
- {
- tt_tFade.EndTimer();
- if(tt_opa)
- {
- var n = Math.round(tt_aV[FADEOUT] / (tt_aV[FADEINTERVAL] * (tt_aV[OPACITY] / tt_opa)));
- tt_Fade(tt_opa, tt_opa, 0, n);
- return;
- }
- }
- tt_tHide.Timer("tt_Hide();", 1, false);
- }
-}
-function tt_Hide()
-{
- if(tt_db && tt_iState)
- {
- tt_OpReHref();
- if(tt_iState & 0x2)
- {
- tt_aElt[0].style.visibility = "hidden";
- tt_ExtCallFncs(0, "Hide");
- }
- tt_tShow.EndTimer();
- tt_tHide.EndTimer();
- tt_tDurt.EndTimer();
- tt_tFade.EndTimer();
- if(!tt_op && !tt_ie)
- {
- tt_tWaitMov.EndTimer();
- tt_bWait = false;
- }
- if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY])
- tt_RemEvtFnc(document, "mouseup", tt_OnLClick);
- tt_ExtCallFncs(0, "Kill");
- // In case of a TagToTip tip, hide converted DOM node and
- // re-insert it into DOM
- if(tt_t2t && !tt_aV[COPYCONTENT])
- tt_UnEl2Tip();
- tt_iState = 0;
- tt_over = null;
- tt_ResetMainDiv();
- if(tt_aElt[tt_aElt.length - 1])
- tt_aElt[tt_aElt.length - 1].style.display = "none";
- }
-}
-function tt_GetElt(id)
-{
- return(document.getElementById ? document.getElementById(id)
- : document.all ? document.all[id]
- : null);
-}
-function tt_GetDivW(el)
-{
- return(el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0);
-}
-function tt_GetDivH(el)
-{
- return(el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0);
-}
-function tt_GetScrollX()
-{
- return(window.pageXOffset || (tt_db ? (tt_db.scrollLeft || 0) : 0));
-}
-function tt_GetScrollY()
-{
- return(window.pageYOffset || (tt_db ? (tt_db.scrollTop || 0) : 0));
-}
-function tt_GetClientW()
-{
- return tt_GetWndCliSiz("Width");
-}
-function tt_GetClientH()
-{
- return tt_GetWndCliSiz("Height");
-}
-function tt_GetEvtX(e)
-{
- return (e ? ((typeof(e.pageX) != tt_u) ? e.pageX : (e.clientX + tt_GetScrollX())) : 0);
-}
-function tt_GetEvtY(e)
-{
- return (e ? ((typeof(e.pageY) != tt_u) ? e.pageY : (e.clientY + tt_GetScrollY())) : 0);
-}
-function tt_AddEvtFnc(el, sEvt, PFnc)
-{
- if(el)
- {
- if(el.addEventListener)
- el.addEventListener(sEvt, PFnc, false);
- else
- el.attachEvent("on" + sEvt, PFnc);
- }
-}
-function tt_RemEvtFnc(el, sEvt, PFnc)
-{
- if(el)
- {
- if(el.removeEventListener)
- el.removeEventListener(sEvt, PFnc, false);
- else
- el.detachEvent("on" + sEvt, PFnc);
- }
-}
-function tt_GetDad(el)
-{
- return(el.parentNode || el.parentElement || el.offsetParent);
-}
-function tt_MovDomNode(el, dadFrom, dadTo)
-{
- if(dadFrom)
- dadFrom.removeChild(el);
- if(dadTo)
- dadTo.appendChild(el);
-}
-
-//====================== PRIVATE ===========================================//
-var tt_aExt = new Array(), // Array of extension objects
-
-tt_db, tt_op, tt_ie, tt_ie56, tt_bBoxOld, // Browser flags
-tt_body,
-tt_ovr_, // HTML element the mouse is currently over
-tt_flagOpa, // Opacity support: 1=IE, 2=Khtml, 3=KHTML, 4=Moz, 5=W3C
-tt_maxPosX, tt_maxPosY,
-tt_iState = 0, // Tooltip active |= 1, shown |= 2, move with mouse |= 4, exclusive |= 8
-tt_opa, // Currently applied opacity
-tt_bJmpVert, tt_bJmpHorz,// Tip temporarily on other side of mouse
-tt_elDeHref, // The tag from which we've removed the href attribute
-// Timer
-tt_tShow = new Number(0), tt_tHide = new Number(0), tt_tDurt = new Number(0),
-tt_tFade = new Number(0), tt_tWaitMov = new Number(0),
-tt_bWait = false,
-tt_u = "undefined";
-
-
-function tt_Init()
-{
- tt_MkCmdEnum();
- // Send old browsers instantly to hell
- if(!tt_Browser() || !tt_MkMainDiv())
- return;
- tt_IsW3cBox();
- tt_OpaSupport();
- tt_AddEvtFnc(document, "mousemove", tt_Move);
- // In Debug mode we search for TagToTip() calls in order to notify
- // the user if they've forgotten to set the TagsToTip config flag
- if(TagsToTip || tt_Debug)
- tt_SetOnloadFnc();
- // Ensure the tip be hidden when the page unloads
- tt_AddEvtFnc(window, "unload", tt_Hide);
-}
-// Creates command names by translating config variable names to upper case
-function tt_MkCmdEnum()
-{
- var n = 0;
- for(var i in config)
- eval("window." + i.toString().toUpperCase() + " = " + n++);
- tt_aV.length = n;
-}
-function tt_Browser()
-{
- var n, nv, n6, w3c;
-
- n = navigator.userAgent.toLowerCase(),
- nv = navigator.appVersion;
- tt_op = (document.defaultView && typeof(eval("w" + "indow" + "." + "o" + "p" + "er" + "a")) != tt_u);
- tt_ie = n.indexOf("msie") != -1 && document.all && !tt_op;
- if(tt_ie)
- {
- var ieOld = (!document.compatMode || document.compatMode == "BackCompat");
- tt_db = !ieOld ? document.documentElement : (document.body || null);
- if(tt_db)
- tt_ie56 = parseFloat(nv.substring(nv.indexOf("MSIE") + 5)) >= 5.5
- && typeof document.body.style.maxHeight == tt_u;
- }
- else
- {
- tt_db = document.documentElement || document.body ||
- (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
- : null);
- if(!tt_op)
- {
- n6 = document.defaultView && typeof document.defaultView.getComputedStyle != tt_u;
- w3c = !n6 && document.getElementById;
- }
- }
- tt_body = (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
- : (document.body || null));
- if(tt_ie || n6 || tt_op || w3c)
- {
- if(tt_body && tt_db)
- {
- if(document.attachEvent || document.addEventListener)
- return true;
- }
- else
- tt_Err("wz_tooltip.js must be included INSIDE the body section,"
- + " immediately after the opening <body> tag.", false);
- }
- tt_db = null;
- return false;
-}
-function tt_MkMainDiv()
-{
- // Create the tooltip DIV
- if(tt_body.insertAdjacentHTML)
- tt_body.insertAdjacentHTML("afterBegin", tt_MkMainDivHtm());
- else if(typeof tt_body.innerHTML != tt_u && document.createElement && tt_body.appendChild)
- tt_body.appendChild(tt_MkMainDivDom());
- if(window.tt_GetMainDivRefs /* FireFox Alzheimer */ && tt_GetMainDivRefs())
- return true;
- tt_db = null;
- return false;
-}
-function tt_MkMainDivHtm()
-{
- return(
- '<div id="WzTtDiV"></div>' +
- (tt_ie56 ? ('<iframe id="WzTtIfRm" src="javascript:false" scrolling="no" frameborder="0" style="filter:Alpha(opacity=0);position:absolute;top:0px;left:0px;display:none;"></iframe>')
- : '')
- );
-}
-function tt_MkMainDivDom()
-{
- var el = document.createElement("div");
- if(el)
- el.id = "WzTtDiV";
- return el;
-}
-function tt_GetMainDivRefs()
-{
- tt_aElt[0] = tt_GetElt("WzTtDiV");
- if(tt_ie56 && tt_aElt[0])
- {
- tt_aElt[tt_aElt.length - 1] = tt_GetElt("WzTtIfRm");
- if(!tt_aElt[tt_aElt.length - 1])
- tt_aElt[0] = null;
- }
- if(tt_aElt[0])
- {
- var css = tt_aElt[0].style;
-
- css.visibility = "hidden";
- css.position = "absolute";
- css.overflow = "hidden";
- return true;
- }
- return false;
-}
-function tt_ResetMainDiv()
-{
- tt_SetTipPos(0, 0);
- tt_aElt[0].innerHTML = "";
- tt_aElt[0].style.width = "0px";
- tt_h = 0;
-}
-function tt_IsW3cBox()
-{
- var css = tt_aElt[0].style;
-
- css.padding = "10px";
- css.width = "40px";
- tt_bBoxOld = (tt_GetDivW(tt_aElt[0]) == 40);
- css.padding = "0px";
- tt_ResetMainDiv();
-}
-function tt_OpaSupport()
-{
- var css = tt_body.style;
-
- tt_flagOpa = (typeof(css.KhtmlOpacity) != tt_u) ? 2
- : (typeof(css.KHTMLOpacity) != tt_u) ? 3
- : (typeof(css.MozOpacity) != tt_u) ? 4
- : (typeof(css.opacity) != tt_u) ? 5
- : (typeof(css.filter) != tt_u) ? 1
- : 0;
-}
-// Ported from http://dean.edwards.name/weblog/2006/06/again/
-// (Dean Edwards et al.)
-function tt_SetOnloadFnc()
-{
- tt_AddEvtFnc(document, "DOMContentLoaded", tt_HideSrcTags);
- tt_AddEvtFnc(window, "load", tt_HideSrcTags);
- if(tt_body.attachEvent)
- tt_body.attachEvent("onreadystatechange",
- function() {
- if(tt_body.readyState == "complete")
- tt_HideSrcTags();
- } );
- if(/WebKit|KHTML/i.test(navigator.userAgent))
- {
- var t = setInterval(function() {
- if(/loaded|complete/.test(document.readyState))
- {
- clearInterval(t);
- tt_HideSrcTags();
- }
- }, 10);
- }
-}
-function tt_HideSrcTags()
-{
- if(!window.tt_HideSrcTags || window.tt_HideSrcTags.done)
- return;
- window.tt_HideSrcTags.done = true;
- if(!tt_HideSrcTagsRecurs(tt_body))
- tt_Err("There are HTML elements to be converted to tooltips.\nIf you"
- + " want these HTML elements to be automatically hidden, you"
- + " must edit wz_tooltip.js, and set TagsToTip in the global"
- + " tooltip configuration to true.", true);
-}
-function tt_HideSrcTagsRecurs(dad)
-{
- var ovr, asT2t;
- // Walk the DOM tree for tags that have an onmouseover or onclick attribute
- // containing a TagToTip('...') call.
- // (.childNodes first since .children is bugous in Safari)
- var a = dad.childNodes || dad.children || null;
-
- for(var i = a ? a.length : 0; i;)
- {--i;
- if(!tt_HideSrcTagsRecurs(a[i]))
- return false;
- ovr = a[i].getAttribute ? (a[i].getAttribute("onmouseover") || a[i].getAttribute("onclick"))
- : (typeof a[i].onmouseover == "function") ? (a[i].onmouseover || a[i].onclick)
- : null;
- if(ovr)
- {
- asT2t = ovr.toString().match(/TagToTip\s*\(\s*'[^'.]+'\s*[\),]/);
- if(asT2t && asT2t.length)
- {
- if(!tt_HideSrcTag(asT2t[0]))
- return false;
- }
- }
- }
- return true;
-}
-function tt_HideSrcTag(sT2t)
-{
- var id, el;
-
- // The ID passed to the found TagToTip() call identifies an HTML element
- // to be converted to a tooltip, so hide that element
- id = sT2t.replace(/.+'([^'.]+)'.+/, "$1");
- el = tt_GetElt(id);
- if(el)
- {
- if(tt_Debug && !TagsToTip)
- return false;
- else
- el.style.display = "none";
- }
- else
- tt_Err("Invalid ID\n'" + id + "'\npassed to TagToTip()."
- + " There exists no HTML element with that ID.", true);
- return true;
-}
-function tt_Tip(arg, t2t)
-{
- if(!tt_db || (tt_iState & 0x8))
- return;
- if(tt_iState)
- tt_Hide();
- if(!tt_Enabled)
- return;
- tt_t2t = t2t;
- if(!tt_ReadCmds(arg))
- return;
- tt_iState = 0x1 | 0x4;
- tt_AdaptConfig1();
- tt_MkTipContent(arg);
- tt_MkTipSubDivs();
- tt_FormatTip();
- tt_bJmpVert = false;
- tt_bJmpHorz = false;
- tt_maxPosX = tt_GetClientW() + tt_GetScrollX() - tt_w - 1;
- tt_maxPosY = tt_GetClientH() + tt_GetScrollY() - tt_h - 1;
- tt_AdaptConfig2();
- // Ensure the tip be shown and positioned before the first onmousemove
- tt_OverInit();
- tt_ShowInit();
- tt_Move();
-}
-function tt_ReadCmds(a)
-{
- var i;
-
- // First load the global config values, to initialize also values
- // for which no command is passed
- i = 0;
- for(var j in config)
- tt_aV[i++] = config[j];
- // Then replace each cached config value for which a command is
- // passed (ensure the # of command args plus value args be even)
- if(a.length & 1)
- {
- for(i = a.length - 1; i > 0; i -= 2)
- tt_aV[a[i - 1]] = a[i];
- return true;
- }
- tt_Err("Incorrect call of Tip() or TagToTip().\n"
- + "Each command must be followed by a value.", true);
- return false;
-}
-function tt_AdaptConfig1()
-{
- tt_ExtCallFncs(0, "LoadConfig");
- // Inherit unspecified title formattings from body
- if(!tt_aV[TITLEBGCOLOR].length)
- tt_aV[TITLEBGCOLOR] = tt_aV[BORDERCOLOR];
- if(!tt_aV[TITLEFONTCOLOR].length)
- tt_aV[TITLEFONTCOLOR] = tt_aV[BGCOLOR];
- if(!tt_aV[TITLEFONTFACE].length)
- tt_aV[TITLEFONTFACE] = tt_aV[FONTFACE];
- if(!tt_aV[TITLEFONTSIZE].length)
- tt_aV[TITLEFONTSIZE] = tt_aV[FONTSIZE];
- if(tt_aV[CLOSEBTN])
- {
- // Use title colours for non-specified closebutton colours
- if(!tt_aV[CLOSEBTNCOLORS])
- tt_aV[CLOSEBTNCOLORS] = new Array("", "", "", "");
- for(var i = 4; i;)
- {--i;
- if(!tt_aV[CLOSEBTNCOLORS][i].length)
- tt_aV[CLOSEBTNCOLORS][i] = (i & 1) ? tt_aV[TITLEFONTCOLOR] : tt_aV[TITLEBGCOLOR];
- }
- // Enforce titlebar be shown
- if(!tt_aV[TITLE].length)
- tt_aV[TITLE] = " ";
- }
- // Circumvents broken display of images and fade-in flicker in Geckos < 1.8
- if(tt_aV[OPACITY] == 100 && typeof tt_aElt[0].style.MozOpacity != tt_u && !Array.every)
- tt_aV[OPACITY] = 99;
- // Smartly shorten the delay for fade-in tooltips
- if(tt_aV[FADEIN] && tt_flagOpa && tt_aV[DELAY] > 100)
- tt_aV[DELAY] = Math.max(tt_aV[DELAY] - tt_aV[FADEIN], 100);
-}
-function tt_AdaptConfig2()
-{
- if(tt_aV[CENTERMOUSE])
- {
- tt_aV[OFFSETX] -= ((tt_w - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0)) >> 1);
- tt_aV[JUMPHORZ] = false;
- }
-}
-// Expose content globally so extensions can modify it
-function tt_MkTipContent(a)
-{
- if(tt_t2t)
- {
- if(tt_aV[COPYCONTENT])
- tt_sContent = tt_t2t.innerHTML;
- else
- tt_sContent = "";
- }
- else
- tt_sContent = a[0];
- tt_ExtCallFncs(0, "CreateContentString");
-}
-function tt_MkTipSubDivs()
-{
- var sCss = 'position:relative;margin:0px;padding:0px;border-width:0px;left:0px;top:0px;line-height:normal;width:auto;',
- sTbTrTd = ' cellspacing="0" cellpadding="0" border="0" style="' + sCss + '"><tbody style="' + sCss + '"><tr><td ';
-
- tt_aElt[0].style.width = tt_GetClientW() + "px";
- tt_aElt[0].innerHTML =
- (''
- + (tt_aV[TITLE].length ?
- ('<div id="WzTiTl" style="position:relative;z-index:1;">'
- + '<table id="WzTiTlTb"' + sTbTrTd + 'id="WzTiTlI" style="' + sCss + '">'
- + tt_aV[TITLE]
- + '</td>'
- + (tt_aV[CLOSEBTN] ?
- ('<td align="right" style="' + sCss
- + 'text-align:right;">'
- + '<span id="WzClOsE" style="position:relative;left:2px;padding-left:2px;padding-right:2px;'
- + 'cursor:' + (tt_ie ? 'hand' : 'pointer')
- + ';" onmouseover="tt_OnCloseBtnOver(1)" onmouseout="tt_OnCloseBtnOver(0)" onclick="tt_HideInit()">'
- + tt_aV[CLOSEBTNTEXT]
- + '</span></td>')
- : '')
- + '</tr></tbody></table></div>')
- : '')
- + '<div id="WzBoDy" style="position:relative;z-index:0;">'
- + '<table' + sTbTrTd + 'id="WzBoDyI" style="' + sCss + '">'
- + tt_sContent
- + '</td></tr></tbody></table></div>'
- + (tt_aV[SHADOW]
- ? ('<div id="WzTtShDwR" style="position:absolute;overflow:hidden;"></div>'
- + '<div id="WzTtShDwB" style="position:relative;overflow:hidden;"></div>')
- : '')
- );
- tt_GetSubDivRefs();
- // Convert DOM node to tip
- if(tt_t2t && !tt_aV[COPYCONTENT])
- tt_El2Tip();
- tt_ExtCallFncs(0, "SubDivsCreated");
-}
-function tt_GetSubDivRefs()
-{
- var aId = new Array("WzTiTl", "WzTiTlTb", "WzTiTlI", "WzClOsE", "WzBoDy", "WzBoDyI", "WzTtShDwB", "WzTtShDwR");
-
- for(var i = aId.length; i; --i)
- tt_aElt[i] = tt_GetElt(aId[i - 1]);
-}
-function tt_FormatTip()
-{
- var css, w, h, pad = tt_aV[PADDING], padT, wBrd = tt_aV[BORDERWIDTH],
- iOffY, iOffSh, iAdd = (pad + wBrd) << 1;
-
- //--------- Title DIV ----------
- if(tt_aV[TITLE].length)
- {
- padT = tt_aV[TITLEPADDING];
- css = tt_aElt[1].style;
- css.background = tt_aV[TITLEBGCOLOR];
- css.paddingTop = css.paddingBottom = padT + "px";
- css.paddingLeft = css.paddingRight = (padT + 2) + "px";
- css = tt_aElt[3].style;
- css.color = tt_aV[TITLEFONTCOLOR];
- if(tt_aV[WIDTH] == -1)
- css.whiteSpace = "nowrap";
- css.fontFamily = tt_aV[TITLEFONTFACE];
- css.fontSize = tt_aV[TITLEFONTSIZE];
- css.fontWeight = "bold";
- css.textAlign = tt_aV[TITLEALIGN];
- // Close button DIV
- if(tt_aElt[4])
- {
- css = tt_aElt[4].style;
- css.background = tt_aV[CLOSEBTNCOLORS][0];
- css.color = tt_aV[CLOSEBTNCOLORS][1];
- css.fontFamily = tt_aV[TITLEFONTFACE];
- css.fontSize = tt_aV[TITLEFONTSIZE];
- css.fontWeight = "bold";
- }
- if(tt_aV[WIDTH] > 0)
- tt_w = tt_aV[WIDTH];
- else
- {
- tt_w = tt_GetDivW(tt_aElt[3]) + tt_GetDivW(tt_aElt[4]);
- // Some spacing between title DIV and closebutton
- if(tt_aElt[4])
- tt_w += pad;
- // Restrict auto width to max width
- if(tt_aV[WIDTH] < -1 && tt_w > -tt_aV[WIDTH])
- tt_w = -tt_aV[WIDTH];
- }
- // Ensure the top border of the body DIV be covered by the title DIV
- iOffY = -wBrd;
- }
- else
- {
- tt_w = 0;
- iOffY = 0;
- }
-
- //-------- Body DIV ------------
- css = tt_aElt[5].style;
- css.top = iOffY + "px";
- if(wBrd)
- {
- css.borderColor = tt_aV[BORDERCOLOR];
- css.borderStyle = tt_aV[BORDERSTYLE];
- css.borderWidth = wBrd + "px";
- }
- if(tt_aV[BGCOLOR].length)
- css.background = tt_aV[BGCOLOR];
- if(tt_aV[BGIMG].length)
- css.backgroundImage = "url(" + tt_aV[BGIMG] + ")";
- css.padding = pad + "px";
- css.textAlign = tt_aV[TEXTALIGN];
- if(tt_aV[HEIGHT])
- {
- css.overflow = "auto";
- if(tt_aV[HEIGHT] > 0)
- css.height = (tt_aV[HEIGHT] + iAdd) + "px";
- else
- tt_h = iAdd - tt_aV[HEIGHT];
- }
- // TD inside body DIV
- css = tt_aElt[6].style;
- css.color = tt_aV[FONTCOLOR];
- css.fontFamily = tt_aV[FONTFACE];
- css.fontSize = tt_aV[FONTSIZE];
- css.fontWeight = tt_aV[FONTWEIGHT];
- css.textAlign = tt_aV[TEXTALIGN];
- if(tt_aV[WIDTH] > 0)
- w = tt_aV[WIDTH];
- // Width like title (if existent)
- else if(tt_aV[WIDTH] == -1 && tt_w)
- w = tt_w;
- else
- {
- // Measure width of the body's inner TD, as some browsers would expand
- // the container and outer body DIV to 100%
- w = tt_GetDivW(tt_aElt[6]);
- // Restrict auto width to max width
- if(tt_aV[WIDTH] < -1 && w > -tt_aV[WIDTH])
- w = -tt_aV[WIDTH];
- }
- if(w > tt_w)
- tt_w = w;
- tt_w += iAdd;
-
- //--------- Shadow DIVs ------------
- if(tt_aV[SHADOW])
- {
- tt_w += tt_aV[SHADOWWIDTH];
- iOffSh = Math.floor((tt_aV[SHADOWWIDTH] * 4) / 3);
- // Bottom shadow
- css = tt_aElt[7].style;
- css.top = iOffY + "px";
- css.left = iOffSh + "px";
- css.width = (tt_w - iOffSh - tt_aV[SHADOWWIDTH]) + "px";
- css.height = tt_aV[SHADOWWIDTH] + "px";
- css.background = tt_aV[SHADOWCOLOR];
- // Right shadow
- css = tt_aElt[8].style;
- css.top = iOffSh + "px";
- css.left = (tt_w - tt_aV[SHADOWWIDTH]) + "px";
- css.width = tt_aV[SHADOWWIDTH] + "px";
- css.background = tt_aV[SHADOWCOLOR];
- }
- else
- iOffSh = 0;
-
- //-------- Container DIV -------
- tt_SetTipOpa(tt_aV[FADEIN] ? 0 : tt_aV[OPACITY]);
- tt_FixSize(iOffY, iOffSh);
-}
-// Fixate the size so it can't dynamically change while the tooltip is moving.
-function tt_FixSize(iOffY, iOffSh)
-{
- var wIn, wOut, h, add, pad = tt_aV[PADDING], wBrd = tt_aV[BORDERWIDTH], i;
-
- tt_aElt[0].style.width = tt_w + "px";
- tt_aElt[0].style.pixelWidth = tt_w;
- wOut = tt_w - ((tt_aV[SHADOW]) ? tt_aV[SHADOWWIDTH] : 0);
- // Body
- wIn = wOut;
- if(!tt_bBoxOld)
- wIn -= (pad + wBrd) << 1;
- tt_aElt[5].style.width = wIn + "px";
- // Title
- if(tt_aElt[1])
- {
- wIn = wOut - ((tt_aV[TITLEPADDING] + 2) << 1);
- if(!tt_bBoxOld)
- wOut = wIn;
- tt_aElt[1].style.width = wOut + "px";
- tt_aElt[2].style.width = wIn + "px";
- }
- // Max height specified
- if(tt_h)
- {
- h = tt_GetDivH(tt_aElt[5]);
- if(h > tt_h)
- {
- if(!tt_bBoxOld)
- tt_h -= (pad + wBrd) << 1;
- tt_aElt[5].style.height = tt_h + "px";
- }
- }
- tt_h = tt_GetDivH(tt_aElt[0]) + iOffY;
- // Right shadow
- if(tt_aElt[8])
- tt_aElt[8].style.height = (tt_h - iOffSh) + "px";
- i = tt_aElt.length - 1;
- if(tt_aElt[i])
- {
- tt_aElt[i].style.width = tt_w + "px";
- tt_aElt[i].style.height = tt_h + "px";
- }
-}
-function tt_DeAlt(el)
-{
- var aKid;
-
- if(el)
- {
- if(el.alt)
- el.alt = "";
- if(el.title)
- el.title = "";
- aKid = el.childNodes || el.children || null;
- if(aKid)
- {
- for(var i = aKid.length; i;)
- tt_DeAlt(aKid[--i]);
- }
- }
-}
-// This hack removes the native tooltips over links in Opera
-function tt_OpDeHref(el)
-{
- if(!tt_op)
- return;
- if(tt_elDeHref)
- tt_OpReHref();
- while(el)
- {
- if(el.hasAttribute && el.hasAttribute("href"))
- {
- el.t_href = el.getAttribute("href");
- el.t_stats = window.status;
- el.removeAttribute("href");
- el.style.cursor = "hand";
- tt_AddEvtFnc(el, "mousedown", tt_OpReHref);
- window.status = el.t_href;
- tt_elDeHref = el;
- break;
- }
- el = tt_GetDad(el);
- }
-}
-function tt_OpReHref()
-{
- if(tt_elDeHref)
- {
- tt_elDeHref.setAttribute("href", tt_elDeHref.t_href);
- tt_RemEvtFnc(tt_elDeHref, "mousedown", tt_OpReHref);
- window.status = tt_elDeHref.t_stats;
- tt_elDeHref = null;
- }
-}
-function tt_El2Tip()
-{
- var css = tt_t2t.style;
-
- // Store previous positioning
- tt_t2t.t_cp = css.position;
- tt_t2t.t_cl = css.left;
- tt_t2t.t_ct = css.top;
- tt_t2t.t_cd = css.display;
- // Store the tag's parent element so we can restore that DOM branch
- // when the tooltip is being hidden
- tt_t2tDad = tt_GetDad(tt_t2t);
- tt_MovDomNode(tt_t2t, tt_t2tDad, tt_aElt[6]);
- css.display = "block";
- css.position = "static";
- css.left = css.top = css.marginLeft = css.marginTop = "0px";
-}
-function tt_UnEl2Tip()
-{
- // Restore positioning and display
- var css = tt_t2t.style;
-
- css.display = tt_t2t.t_cd;
- tt_MovDomNode(tt_t2t, tt_GetDad(tt_t2t), tt_t2tDad);
- css.position = tt_t2t.t_cp;
- css.left = tt_t2t.t_cl;
- css.top = tt_t2t.t_ct;
- tt_t2tDad = null;
-}
-function tt_OverInit()
-{
- if(window.event)
- tt_over = window.event.target || window.event.srcElement;
- else
- tt_over = tt_ovr_;
- tt_DeAlt(tt_over);
- tt_OpDeHref(tt_over);
-}
-function tt_ShowInit()
-{
- tt_tShow.Timer("tt_Show()", tt_aV[DELAY], true);
- if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY])
- tt_AddEvtFnc(document, "mouseup", tt_OnLClick);
-}
-function tt_Show()
-{
- var css = tt_aElt[0].style;
-
- // Override the z-index of the topmost wz_dragdrop.js D&D item
- css.zIndex = Math.max((window.dd && dd.z) ? (dd.z + 2) : 0, 1010);
- if(tt_aV[STICKY] || !tt_aV[FOLLOWMOUSE])
- tt_iState &= ~0x4;
- if(tt_aV[EXCLUSIVE])
- tt_iState |= 0x8;
- if(tt_aV[DURATION] > 0)
- tt_tDurt.Timer("tt_HideInit()", tt_aV[DURATION], true);
- tt_ExtCallFncs(0, "Show")
- css.visibility = "visible";
- tt_iState |= 0x2;
- if(tt_aV[FADEIN])
- tt_Fade(0, 0, tt_aV[OPACITY], Math.round(tt_aV[FADEIN] / tt_aV[FADEINTERVAL]));
- tt_ShowIfrm();
-}
-function tt_ShowIfrm()
-{
- if(tt_ie56)
- {
- var ifrm = tt_aElt[tt_aElt.length - 1];
- if(ifrm)
- {
- var css = ifrm.style;
- css.zIndex = tt_aElt[0].style.zIndex - 1;
- css.display = "block";
- }
- }
-}
-function tt_Move(e)
-{
- if(e)
- tt_ovr_ = e.target || e.srcElement;
- e = e || window.event;
- if(e)
- {
- tt_musX = tt_GetEvtX(e);
- tt_musY = tt_GetEvtY(e);
- }
- if(tt_iState & 0x4)
- {
- // Prevent jam of mousemove events
- if(!tt_op && !tt_ie)
- {
- if(tt_bWait)
- return;
- tt_bWait = true;
- tt_tWaitMov.Timer("tt_bWait = false;", 1, true);
- }
- if(tt_aV[FIX])
- {
- tt_iState &= ~0x4;
- tt_PosFix();
- }
- else if(!tt_ExtCallFncs(e, "MoveBefore"))
- tt_SetTipPos(tt_Pos(0), tt_Pos(1));
- tt_ExtCallFncs([tt_musX, tt_musY], "MoveAfter")
- }
-}
-function tt_Pos(iDim)
-{
- var iX, bJmpMod, cmdAlt, cmdOff, cx, iMax, iScrl, iMus, bJmp;
-
- // Map values according to dimension to calculate
- if(iDim)
- {
- bJmpMod = tt_aV[JUMPVERT];
- cmdAlt = ABOVE;
- cmdOff = OFFSETY;
- cx = tt_h;
- iMax = tt_maxPosY;
- iScrl = tt_GetScrollY();
- iMus = tt_musY;
- bJmp = tt_bJmpVert;
- }
- else
- {
- bJmpMod = tt_aV[JUMPHORZ];
- cmdAlt = LEFT;
- cmdOff = OFFSETX;
- cx = tt_w;
- iMax = tt_maxPosX;
- iScrl = tt_GetScrollX();
- iMus = tt_musX;
- bJmp = tt_bJmpHorz;
- }
- if(bJmpMod)
- {
- if(tt_aV[cmdAlt] && (!bJmp || tt_CalcPosAlt(iDim) >= iScrl + 16))
- iX = tt_PosAlt(iDim);
- else if(!tt_aV[cmdAlt] && bJmp && tt_CalcPosDef(iDim) > iMax - 16)
- iX = tt_PosAlt(iDim);
- else
- iX = tt_PosDef(iDim);
- }
- else
- {
- iX = iMus;
- if(tt_aV[cmdAlt])
- iX -= cx + tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
- else
- iX += tt_aV[cmdOff];
- }
- // Prevent tip from extending past clientarea boundary
- if(iX > iMax)
- iX = bJmpMod ? tt_PosAlt(iDim) : iMax;
- // In case of insufficient space on both sides, ensure the left/upper part
- // of the tip be visible
- if(iX < iScrl)
- iX = bJmpMod ? tt_PosDef(iDim) : iScrl;
- return iX;
-}
-function tt_PosDef(iDim)
-{
- if(iDim)
- tt_bJmpVert = tt_aV[ABOVE];
- else
- tt_bJmpHorz = tt_aV[LEFT];
- return tt_CalcPosDef(iDim);
-}
-function tt_PosAlt(iDim)
-{
- if(iDim)
- tt_bJmpVert = !tt_aV[ABOVE];
- else
- tt_bJmpHorz = !tt_aV[LEFT];
- return tt_CalcPosAlt(iDim);
-}
-function tt_CalcPosDef(iDim)
-{
- return iDim ? (tt_musY + tt_aV[OFFSETY]) : (tt_musX + tt_aV[OFFSETX]);
-}
-function tt_CalcPosAlt(iDim)
-{
- var cmdOff = iDim ? OFFSETY : OFFSETX;
- var dx = tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
- if(tt_aV[cmdOff] > 0 && dx <= 0)
- dx = 1;
- return((iDim ? (tt_musY - tt_h) : (tt_musX - tt_w)) - dx);
-}
-function tt_PosFix()
-{
- var iX, iY;
-
- if(typeof(tt_aV[FIX][0]) == "number")
- {
- iX = tt_aV[FIX][0];
- iY = tt_aV[FIX][1];
- }
- else
- {
- if(typeof(tt_aV[FIX][0]) == "string")
- el = tt_GetElt(tt_aV[FIX][0]);
- // First slot in array is direct reference to HTML element
- else
- el = tt_aV[FIX][0];
- iX = tt_aV[FIX][1];
- iY = tt_aV[FIX][2];
- // By default, vert pos is related to bottom edge of HTML element
- if(!tt_aV[ABOVE] && el)
- iY += tt_GetDivH(el);
- for(; el; el = el.offsetParent)
- {
- iX += el.offsetLeft || 0;
- iY += el.offsetTop || 0;
- }
- }
- // For a fixed tip positioned above the mouse, use the bottom edge as anchor
- // (recommended by Christophe Rebeschini, 31.1.2008)
- if(tt_aV[ABOVE])
- iY -= tt_h;
- tt_SetTipPos(iX, iY);
-}
-function tt_Fade(a, now, z, n)
-{
- if(n)
- {
- now += Math.round((z - now) / n);
- if((z > a) ? (now >= z) : (now <= z))
- now = z;
- else
- tt_tFade.Timer(
- "tt_Fade("
- + a + "," + now + "," + z + "," + (n - 1)
- + ")",
- tt_aV[FADEINTERVAL],
- true
- );
- }
- now ? tt_SetTipOpa(now) : tt_Hide();
-}
-function tt_SetTipOpa(opa)
-{
- // To circumvent the opacity nesting flaws of IE, we set the opacity
- // for each sub-DIV separately, rather than for the container DIV.
- tt_SetOpa(tt_aElt[5], opa);
- if(tt_aElt[1])
- tt_SetOpa(tt_aElt[1], opa);
- if(tt_aV[SHADOW])
- {
- opa = Math.round(opa * 0.8);
- tt_SetOpa(tt_aElt[7], opa);
- tt_SetOpa(tt_aElt[8], opa);
- }
-}
-function tt_OnCloseBtnOver(iOver)
-{
- var css = tt_aElt[4].style;
-
- iOver <<= 1;
- css.background = tt_aV[CLOSEBTNCOLORS][iOver];
- css.color = tt_aV[CLOSEBTNCOLORS][iOver + 1];
-}
-function tt_OnLClick(e)
-{
- // Ignore right-clicks
- e = e || window.event;
- if(!((e.button && e.button & 2) || (e.which && e.which == 3)))
- {
- if(tt_aV[CLICKSTICKY] && (tt_iState & 0x4))
- {
- tt_aV[STICKY] = true;
- tt_iState &= ~0x4;
- }
- else if(tt_aV[CLICKCLOSE])
- tt_HideInit();
- }
-}
-function tt_Int(x)
-{
- var y;
-
- return(isNaN(y = parseInt(x)) ? 0 : y);
-}
-Number.prototype.Timer = function(s, iT, bUrge)
-{
- if(!this.value || bUrge)
- this.value = window.setTimeout(s, iT);
-}
-Number.prototype.EndTimer = function()
-{
- if(this.value)
- {
- window.clearTimeout(this.value);
- this.value = 0;
- }
-}
-function tt_GetWndCliSiz(s)
-{
- var db, y = window["inner" + s], sC = "client" + s, sN = "number";
- if(typeof y == sN)
- {
- var y2;
- return(
- // Gecko or Opera with scrollbar
- // ... quirks mode
- ((db = document.body) && typeof(y2 = db[sC]) == sN && y2 && y2 <= y) ? y2
- // ... strict mode
- : ((db = document.documentElement) && typeof(y2 = db[sC]) == sN && y2 && y2 <= y) ? y2
- // No scrollbar, or clientarea size == 0, or other browser (KHTML etc.)
- : y
- );
- }
- // IE
- return(
- // document.documentElement.client+s functional, returns > 0
- ((db = document.documentElement) && (y = db[sC])) ? y
- // ... not functional, in which case document.body.client+s
- // is the clientarea size, fortunately
- : document.body[sC]
- );
-}
-function tt_SetOpa(el, opa)
-{
- var css = el.style;
-
- tt_opa = opa;
- if(tt_flagOpa == 1)
- {
- if(opa < 100)
- {
- // Hacks for bugs of IE:
- // 1.) Once a CSS filter has been applied, fonts are no longer
- // anti-aliased, so we store the previous 'non-filter' to be
- // able to restore it
- if(typeof(el.filtNo) == tt_u)
- el.filtNo = css.filter;
- // 2.) A DIV cannot be made visible in a single step if an
- // opacity < 100 has been applied while the DIV was hidden
- var bVis = css.visibility != "hidden";
- // 3.) In IE6, applying an opacity < 100 has no effect if the
- // element has no layout (position, size, zoom, ...)
- css.zoom = "100%";
- if(!bVis)
- css.visibility = "visible";
- css.filter = "alpha(opacity=" + opa + ")";
- if(!bVis)
- css.visibility = "hidden";
- }
- else if(typeof(el.filtNo) != tt_u)
- // Restore 'non-filter'
- css.filter = el.filtNo;
- }
- else
- {
- opa /= 100.0;
- switch(tt_flagOpa)
- {
- case 2:
- css.KhtmlOpacity = opa; break;
- case 3:
- css.KHTMLOpacity = opa; break;
- case 4:
- css.MozOpacity = opa; break;
- case 5:
- css.opacity = opa; break;
- }
- }
-}
-function tt_Err(sErr, bIfDebug)
-{
- if(tt_Debug || !bIfDebug)
- alert("Tooltip Script Error Message:\n\n" + sErr);
-}
-
-//============ EXTENSION (PLUGIN) MANAGER ===============//
-function tt_ExtCmdEnum()
-{
- var s;
-
- // Add new command(s) to the commands enum
- for(var i in config)
- {
- s = "window." + i.toString().toUpperCase();
- if(eval("typeof(" + s + ") == tt_u"))
- {
- eval(s + " = " + tt_aV.length);
- tt_aV[tt_aV.length] = null;
- }
- }
-}
-function tt_ExtCallFncs(arg, sFnc)
-{
- var b = false;
- for(var i = tt_aExt.length; i;)
- {--i;
- var fnc = tt_aExt[i]["On" + sFnc];
- // Call the method the extension has defined for this event
- if(fnc && fnc(arg))
- b = true;
- }
- return b;
-}
-
-tt_Init();
'Introduction of clients' => 'Einführung von Mandanten',
'Inv. Duedate' => 'Rg. Fälligkeit',
'Invalid' => 'Ungültig',
+ 'Invalid duration format' => 'Falsches Format für Zeitdauer',
'Invalid follow-up ID.' => 'Ungültige Wiedervorlage-ID.',
'Invalid quantity.' => 'Die Mengenangabe ist ungültig.',
'Invalid request type \'#1\'' => 'Ungültiger Request-Typ \'#1\'',
'Proposal' => 'Vorschlag',
'Proposals' => 'Vorschläge',
'Prozentual/Absolut' => 'Prozentual/Absolut',
+ 'Purchase Delivery Order' => 'Einkaufslieferschein',
'Purchase Delivery Orders' => 'Einkaufslieferscheine',
'Purchase Delivery Orders deleteable' => 'Einkaufslieferscheine löschbar',
'Purchase Invoice' => 'Einkaufsrechnung',
'Receipt, payment, reconciliation' => 'Zahlungseingang, Zahlungsausgang, Kontenabgleich',
'Receipts' => 'Zahlungseingänge',
'Receivables' => 'Forderungen',
- 'Rechnungsnummer' => 'Rechnungsnummer',
'Reconcile' => 'Abgleichen',
'Reconciliation' => 'Kontenabgleich',
'Reconciliation with bank' => 'Kontenabgleich mit Bank',
'Saldo neu' => 'Saldo neu',
'Saldo per' => 'Saldo per',
'Sale Prices' => 'Verkaufspreise',
+ 'Sales Delivery Order' => 'Verkaufslieferschein',
'Sales Delivery Orders' => 'Verkaufslieferscheine',
'Sales Delivery Orders deleteable' => 'Verkaufslieferscheine löschbar',
'Sales Invoice' => 'Rechnung',
--- /dev/null
+#!/usr/bin/perl
+# -*- coding: utf-8; -*-
+# vim: fenc=utf-8
+
+use utf8;
+
+$self->{more_texts} = {
+ 'Add Machine' => 'Maschine erfassen',
+ 'Add Service Contract' => 'Wartungsvertrag erfassen',
+ 'Admin' => 'Administration',
+ 'Appointment Category' => 'Termin Kategorie',
+ 'Appointments' => 'Termine',
+ 'CRM admin' => '',
+ 'CRM create customers, vendors and contacts' => '',
+ 'CRM follow up' => '',
+ 'CRM know how' => '',
+ 'CRM notices' => '',
+ 'CRM opportunity' => '',
+ 'CRM optional software' => '',
+ 'CRM other' => '',
+ 'CRM search' => '',
+ 'CRM send email' => '',
+ 'CRM services' => '',
+ 'CRM status' => '',
+ 'CRM termin' => '',
+ 'CRM user' => '',
+ 'CRM' => 'CRM',
+ 'Catalog' => 'Katalog',
+ 'DHL' => 'DHL',
+ 'Document Template' => 'Dokumentvorlage',
+ 'Documents' => 'Dokumente',
+ 'Etikett' => 'Etikett',
+ 'EuR' => 'EuR',
+ 'Knowledge' => 'Wissen',
+ 'Label' => 'Etikett',
+ 'Machine' => 'Maschine',
+ 'Message' => 'Nachricht',
+ 'Opportunity' => 'Auftragschance',
+ 'Other' => 'Sonstiges',
+ 'Packliste' => 'Packliste',
+ 'Partsedit' => 'Wareneditor',
+ 'Person' => 'Person',
+ 'Service Contract' => 'Wartungsvertrag',
+ 'Time Tracking' => 'Zeiterfassung',
+ 'User Groups' => 'Gruppen',
+ 'Warehouse correction' => 'Lagerkorrektur',
+ 'Warehouse list' => 'Inventurliste',
+ 'ZM' => 'ZM',
+ 'eBayImporter' => 'eBay-Importierer',
+};
+
+1;
+++ /dev/null
-[Users, Clients and User Groups]
-
-[Users, Clients and User Groups--List Users, Clients and User Groups]
-module=controller.pl
-action=Admin/show
-
-[Users, Clients and User Groups--Add User]
-module=controller.pl
-action=Admin/new_user
-
-[Users, Clients and User Groups--Add Client]
-module=controller.pl
-action=Admin/new_client
-
-[Users, Clients and User Groups--Add User Group]
-module=controller.pl
-action=Admin/new_group
-
-[Database Management]
-
-[Database Management--Create Dataset]
-module=controller.pl
-action=Admin/create_dataset_login
-
-[Database Management--Delete Dataset]
-module=controller.pl
-action=Admin/delete_dataset_login
-
-[Printer Management]
-
-[Printer Management--List Printers]
-module=controller.pl
-action=Admin/list_printers
-
-[Printer Management--Add Printer]
-module=controller.pl
-action=Admin/new_printer
-
-[System]
-
-[System--Lock and unlock installation]
-module=controller.pl
-action=Admin/show_lock
-
-[System--Documentation (in German)]
-href=doc/kivitendo-Dokumentation.pdf
-target=_blank
-
-[System--kivitendo website (external)]
-href=http://www.kivitendo.de/
-target=_blank
-
-[System--To user login]
-module=controller.pl
-action=LoginScreen/user_login
-
-[System--Logout]
-module=controller.pl
-action=Admin/logout
--- /dev/null
+---
+- id: users_clients_and_user_groups
+ name: Users, Clients and User Groups
+ order: 100
+- parent: users_clients_and_user_groups
+ id: users_clients_and_user_groups_list_users_clients_and_user_groups
+ name: List Users, Clients and User Groups
+ order: 100
+ params:
+ action: Admin/show
+- parent: users_clients_and_user_groups
+ id: users_clients_and_user_groups_add_user
+ name: Add User
+ order: 200
+ params:
+ action: Admin/new_user
+- parent: users_clients_and_user_groups
+ id: users_clients_and_user_groups_add_client
+ name: Add Client
+ order: 300
+ params:
+ action: Admin/new_client
+- parent: users_clients_and_user_groups
+ id: users_clients_and_user_groups_add_user_group
+ name: Add User Group
+ order: 400
+ params:
+ action: Admin/new_group
+- id: database_management
+ name: Database Management
+ order: 200
+- parent: database_management
+ id: database_management_create_dataset
+ name: Create Dataset
+ order: 100
+ params:
+ action: Admin/create_dataset_login
+- parent: database_management
+ id: database_management_delete_dataset
+ name: Delete Dataset
+ order: 200
+ params:
+ action: Admin/delete_dataset_login
+- id: printer_management
+ name: Printer Management
+ order: 300
+- parent: printer_management
+ id: printer_management_list_printers
+ name: List Printers
+ order: 100
+ params:
+ action: Admin/list_printers
+- parent: printer_management
+ id: printer_management_add_printer
+ name: Add Printer
+ order: 200
+ params:
+ action: Admin/new_printer
+- id: system
+ name: System
+ icon: system
+ order: 400
+- parent: system
+ id: system_lock_and_unlock_installation
+ name: Lock and unlock installation
+ order: 100
+ params:
+ action: Admin/show_lock
+- parent: system
+ id: system_documentation_in_german_
+ name: Documentation (in German)
+ order: 200
+ href: doc/kivitendo-Dokumentation.pdf
+ target: _blank
+- parent: system
+ id: system_kivitendo_website_external_
+ name: kivitendo website (external)
+ order: 300
+ href: http://www.kivitendo.de/
+ target: _blank
+- parent: system
+ id: system_to_user_login
+ name: To user login
+ order: 400
+ params:
+ action: LoginScreen/user_login
+- parent: system
+ id: system_logout
+ name: Logout
+ order: 500
+ params:
+ action: Admin/logout
+++ /dev/null
-[CRM]
-
-[CRM--Search]
-ACCESS=crm_search
-module=crm/getData.php
-
-[CRM--Add]
-submenu=1
-
-[CRM--Add--Customer]
-ACCESS=crm_new
-module=crm/firmen3.php
-Q=C
-
-[CRM--Add--Vendor]
-ACCESS=crm_new
-module=crm/firmen3.php
-Q=V
-
-[CRM--Add--Person]
-ACCESS=crm_new
-module=crm/personen3.php
-
-[CRM--Appointments]
-ACCESS=crm_termin
-module=crm/termin.php
-
-[CRM--Opportunity]
-ACCESS=crm_opportunity
-module=crm/opportunity.php
-
-[CRM--Follow-Up]
-ACCESS=crm_follow
-module=crm/wvl1.php
-
-[CRM--E-mail]
-ACCESS=crm_email
-module=crm/mail.php
-
-[CRM--Knowledge]
-ACCESS=crm_knowhow
-module=crm/wissen.php
-
-[CRM--Memo]
-ACCESS=crm_notices
-module=crm/postit.php
-
-[CRM--Documents]
-ACCESS=crm_other
-module=crm/dokument.php
-
-[CRM--Time Tracking]
-ACCESS=crm_service
-module=crm/timetrack.php
-
-[CRM--Other]
-submenu=1
-
-[CRM--Other--Etikett]
-ACCESS=crm_other
-module=crm/prtetikett.php
-target=_blank
-
-[CRM--Other--DHL]
-ACCESS=crm_other
-module=crm/dhl.php
-
-[CRM--Other--eBayImporter]
-ACCESS=crm_other
-module=crm/ebayImporter.php
-
-[CRM--Other--Catalog]
-ACCESS=crm_other
-module=crm/katalog.php
-
-[CRM--Other--Warehouse list]
-ACCESS=crm_other
-module=crm/inventur.php
-
-[CRM--Other--Warehouse correction]
-ACCESS=crm_admin
-module=crm/inventurlager.php
-
-[CRM--Other--Partsedit]
-ACCESS=crm_other
-module=crm/partsedit.php
-
-[CRM--Other--Packliste]
-ACCESS=crm_other
-module=crm/packliste.php
-
-[CRM--Other--EuR]
-ACCESS=crm_other
-module=crm/eur.php
-
-[CRM--Other--ZM]
-ACCESS=crm_other
-module=crm/ustva_zm.php
-
-
-[CRM--Service]
-submenu=1
-
-[CRM--Service--Service Contract]
-ACCESS=crm_service
-module=crm/vertrag1.php
-
-[CRM--Service--Add Service Contract]
-ACCESS=crm_service
-module=crm/vertrag3.php
-
-[CRM--Service--Machine]
-ACCESS=crm_service
-module=crm/maschine1.php
-
-[CRM--Service--Add Machine]
-ACCESS=crm_service
-module=crm/maschine3.php
-
-[CRM--Admin]
-submenu=1
-
-[CRM--Admin--Document Template]
-ACCESS=crm_admin
-module=crm/dokument1.php
-
-[CRM--Admin--Label]
-ACCESS=crm_admin
-module=crm/aufkleber_def.php
-
-[CRM--Admin--Appointment Category]
-ACCESS=crm_admin
-module=crm/tcatedit.php
-
-[CRM--Admin--Message]
-ACCESS=crm_admin
-module=crm/user3.php
-
-[CRM--Admin--Client]
-ACCESS=crm_adminstatus
-module=crm/mandant.php
-
-[CRM--Admin--User Groups]
-ACCESS=crm_admin
-module=crm/user2.php
-
-[CRM--Admin--User]
-ACCESS=crm_adminuser
-module=crm/user1.php
-
-[CRM--Admin--DHL]
-ACCESS=crm_adminuser
-module=crm/dhladm.php
-
-[CRM--Admin--Status]
-ACCESS=crm_adminstatus
-module=crm/status.php
+++ /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--Add Requirement Spec Template]
-ACCESS=requirement_spec_edit
-module=controller.pl
-action=RequirementSpec/new
-is_template=1
-
-[Master Data--Update Prices]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=search_update_prices
-
-[Master Data--Price Rules]
-ACCESS=part_service_assembly_edit
-module=controller.pl
-action=PriceRule/list
-filter.obsolete=0
-
-[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/list
-filter.active=active
-filter.valid=valid
-
-[Master Data--Reports--Requirement Spec Templates]
-ACCESS=requirement_spec_edit
-module=controller.pl
-action=RequirementSpec/list
-is_template=1
-
-[AR]
-
-[AR--Add Requirement Spec]
-ACCESS=requirement_spec_edit
-module=controller.pl
-action=RequirementSpec/new
-
-[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--Add Letter]
-ACCESS=sales_letter_edit
-module=letter.pl
-action=add
-
-[AR--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[AR--Reports--Requirement Specs]
-ACCESS=requirement_spec_edit
-module=controller.pl
-action=RequirementSpec/list
-
-[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=delivery_plan
-module=controller.pl
-action=DeliveryPlan/list
-vc=customer
-mode=delivery_plan
-
-[AR--Reports--Delivery Value Report]
-ACCESS=delivery_value_report
-module=controller.pl
-action=DeliveryPlan/list
-vc=customer
-mode=delivery_value_report
-
-
-[AR--Reports--Financial Controlling]
-ACCESS=sales_order_edit
-module=controller.pl
-action=FinancialControllingReport/list
-
-[AR--Reports--Letters]
-ACCESS=sales_letter_report
-module=letter.pl
-action=search
-
-[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
-INSTANCE_CONF=allow_new_purchase_delivery_order
-module=do.pl
-action=add
-type=purchase_delivery_order
-
-[AP--Add Vendor Invoice]
-ACCESS=vendor_invoice_edit
-INSTANCE_CONF=allow_new_purchase_invoice
-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
-
-[AP--Reports--Delivery Plan]
-ACCESS=delivery_plan
-module=controller.pl
-action=DeliveryPlan/list
-vc=vendor
-mode=delivery_plan
-
-[AP--Reports--Delivery Value Report]
-ACCESS=delivery_value_report
-module=controller.pl
-action=DeliveryPlan/list
-vc=vendor
-mode=delivery_value_report
-
-[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--DATEV - Export Assistent]
-ACCESS=datev_export
-module=datev.pl
-action=export
-
-
-
-
-[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]
-
-[Cash--Receipt]
-ACCESS=cash
-module=cp.pl
-action=payment
-type=receipt
-vc=customer
-
-[Cash--Payment]
-ACCESS=cash
-module=cp.pl
-action=payment
-type=check
-vc=vendor
-
-[Cash--Bank collection via SEPA]
-ACCESS=cash
-module=sepa.pl
-action=bank_transfer_add
-vc=customer
-
-[Cash--Bank transfer via SEPA]
-ACCESS=cash
-module=sepa.pl
-action=bank_transfer_add
-vc=vendor
-
-[Cash--Bank Import]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Cash--Bank Import--CSV]
-ACCESS=bank_transaction
-module=controller.pl
-action=CsvImport/new
-profile.type=bank_transactions
-
-[Cash--Bank Import--MT940]
-ACCESS=bank_transaction
-module=controller.pl
-action=BankImport/upload_mt940
-
-[Cash--Bank transactions MT940]
-ACCESS=bank_transaction
-module=controller.pl
-action=BankTransaction/search
-
-[Cash--Reconciliation with bank]
-ACCESS=bank_transaction
-module=controller.pl
-action=Reconciliation/search
-next_sub=Reconciliation/reconciliation
-
-[Cash--Reconciliation]
-ACCESS=cash
-module=rc.pl
-action=reconciliation
-
-[Cash--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Cash--Reports--Receipts]
-ACCESS=cash
-module=rp.pl
-action=report
-report=receipts
-
-[Cash--Reports--Payments]
-ACCESS=cash
-module=rp.pl
-action=report
-report=payments
-
-[Cash--Reports--Bank collections via SEPA]
-ACCESS=cash
-module=sepa.pl
-action=bank_transfer_search
-vc=customer
-
-[Cash--Reports--Bank transfers via SEPA]
-ACCESS=cash
-module=sepa.pl
-action=bank_transfer_search
-vc=vendor
-
-[Cash--Reports--Bank transactions]
-ACCESS=bank_transaction
-module=controller.pl
-action=BankTransaction/list_all
-
-[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--Income Statement]
-ACCESS=report
-module=rp.pl
-action=report
-report=income_statement
-
-[Reports--BWA]
-ACCESS=report
-module=rp.pl
-action=report
-report=bwa
-
-[Reports--Balance Sheet]
-ACCESS=report
-module=rp.pl
-action=report
-report=balance_sheet
-
-[Reports--UStVa]
-ACCESS=advance_turnover_tax_return
-module=ustva.pl
-action=report
-
-[Reports--Projecttransactions]
-ACCESS=report
-module=rp.pl
-action=report
-report=projects
-
-[Reports--Financial Overview]
-ACCESS=report
-module=controller.pl
-action=FinancialOverview/list
-
-[Reports--Liquidity projection]
-ACCESS=report
-module=controller.pl
-action=LiquidityProjection/show
-
-[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--UStVa Einstellungen]
-module=ustva.pl
-action=config_step1
-
-[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=controller.pl
-action=Buchungsgruppen/list
-
-[System--Taxzones]
-module=controller.pl
-action=Taxzones/list
-
-[System--Taxes]
-module=am.pl
-action=list_tax
-
-[System--Bank accounts]
-module=controller.pl
-action=BankAccount/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--Project Types]
-module=controller.pl
-action=ProjectType/list
-
-[System--Project Status]
-module=controller.pl
-action=ProjectStatus/list
-
-[System--Requirement specs]
-module=menu.pl
-action=acc_menu
-target=acc_menu
-submenu=1
-
-[System--Requirement specs--Pre-defined Texts]
-module=controller.pl
-action=RequirementSpecPredefinedText/list
-
-[System--Requirement specs--Requirement Spec Types]
-module=controller.pl
-action=RequirementSpecType/list
-
-[System--Requirement specs--Requirement Spec Statuses]
-module=controller.pl
-action=RequirementSpecStatus/list
-
-[System--Requirement specs--Complexities]
-module=controller.pl
-action=RequirementSpecComplexity/list
-
-[System--Requirement specs--Risks]
-module=controller.pl
-action=RequirementSpecRisk/list
-
-[System--Requirement specs--Acceptance Statuses]
-module=controller.pl
-action=RequirementSpecAcceptanceStatus/list
-
-[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--Delivery Terms]
-module=controller.pl
-action=DeliveryTerm/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--Inventories]
-module=controller.pl
-action=CsvImport/new
-profile.type=inventories
-
-[System--Import CSV--Projects]
-module=controller.pl
-action=CsvImport/new
-profile.type=projects
-
-[System--Import CSV--Orders]
-module=controller.pl
-action=CsvImport/new
-profile.type=orders
-
-[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--Internal Phone List]
-module=controller.pl
-action=CTI/list_internal_extensions
-
-[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
--- /dev/null
+# This is the main menu config file for user space menu entries.
+#
+# Each menu entry can have the following properties:
+#
+# parnet: the id of a higher node in the tree, top-level node if missing
+# id: a unique identifier used by parent links and for overloading
+# name: translatable text for display
+# icon: stripped name of an icon for this menu entry
+# order: numeric value. lower will be displayed first
+# access: boolean expression of the rights needed to display and access this entry
+# ( ) & | are supported. if binary operator is missing the last
+# operator in same scope is repeated, or "|" if none used in scope
+# yet. client config entrys can be used as rights by prefixing them
+# with "client/". If missing, access will be granted.
+#
+# Example:
+# client/feature_default_enabled | ( feature & system )
+#
+# href: fully qualified external link
+# module: defaults to "controller.pl". Should ne be present if the link is for
+# Controller::Base dispatching to enable routing. otherwise with
+# script will be used.
+# target: target window for link. ex: "_blank"
+# params: additional url parameter
+---
+- id: master_data
+ name: Master Data
+ icon: master_data
+ order: 100
+- parent: master_data
+ id: master_data_add_customer
+ name: Add Customer
+ icon: customer_add
+ order: 100
+ access: customer_vendor_edit
+ params:
+ action: CustomerVendor/add
+ db: customer
+- parent: master_data
+ id: master_data_add_vendor
+ name: Add Vendor
+ icon: vendor_add
+ order: 200
+ access: customer_vendor_edit
+ params:
+ action: CustomerVendor/add
+ db: vendor
+- parent: master_data
+ id: master_data_add_part
+ name: Add Part
+ icon: part_add
+ order: 300
+ access: part_service_assembly_edit
+ module: ic.pl
+ params:
+ action: add
+ item: part
+- parent: master_data
+ id: master_data_add_service
+ name: Add Service
+ icon: service_add
+ order: 400
+ access: part_service_assembly_edit
+ module: ic.pl
+ params:
+ action: add
+ item: service
+- parent: master_data
+ id: master_data_add_assembly
+ name: Add Assembly
+ icon: assembly_add
+ order: 500
+ access: part_service_assembly_edit
+ module: ic.pl
+ params:
+ action: add
+ item: assembly
+- parent: master_data
+ id: master_data_add_project
+ name: Add Project
+ icon: project_add
+ order: 600
+ access: project_edit
+ params:
+ action: Project/new
+- parent: master_data
+ id: master_data_add_requirement_spec_template
+ name: Add Requirement Spec Template
+ order: 700
+ access: requirement_spec_edit
+ params:
+ action: RequirementSpec/new
+ is_template: 1
+- parent: master_data
+ id: master_data_update_prices
+ name: Update Prices
+ icon: prices_update
+ order: 800
+ access: part_service_assembly_edit
+ module: ic.pl
+ params:
+ action: search_update_prices
+- parent: master_data
+ id: master_data_price_rules
+ name: Price Rules
+ order: 900
+ access: part_service_assembly_edit
+ params:
+ action: PriceRule/list
+ filter.obsolete: 0
+- parent: master_data
+ id: master_data_reports
+ name: Reports
+ icon: master_data_report
+ order: 1000
+- parent: master_data_reports
+ id: master_data_reports_customers
+ name: Customers
+ icon: customer_report
+ order: 100
+ access: customer_vendor_edit
+ params:
+ action: CustomerVendor/search
+ db: customer
+- parent: master_data_reports
+ id: master_data_reports_vendors
+ name: Vendors
+ icon: vendor_report
+ order: 200
+ access: customer_vendor_edit
+ params:
+ action: CustomerVendor/search
+ db: vendor
+- parent: master_data_reports
+ id: master_data_reports_contacts
+ name: Contacts
+ order: 300
+ access: customer_vendor_edit
+ params:
+ action: CustomerVendor/search_contact
+ db: customer
+- parent: master_data_reports
+ id: master_data_reports_parts
+ name: Parts
+ icon: part_report
+ order: 400
+ access: part_service_assembly_details
+ module: ic.pl
+ params:
+ action: search
+ searchitems: part
+- parent: master_data_reports
+ id: master_data_reports_services
+ name: Services
+ icon: service_report
+ order: 500
+ access: part_service_assembly_details
+ module: ic.pl
+ params:
+ action: search
+ searchitems: service
+- parent: master_data_reports
+ id: master_data_reports_assemblies
+ name: Assemblies
+ icon: assembly_report
+ order: 600
+ access: part_service_assembly_details
+ module: ic.pl
+ params:
+ action: search
+ searchitems: assembly
+- parent: master_data_reports
+ id: master_data_reports_projects
+ name: Projects
+ icon: project_report
+ order: 700
+ access: project_edit
+ params:
+ action: Project/list
+ filter.active: active
+ filter.valid: valid
+- parent: master_data_reports
+ id: master_data_reports_requirement_spec_templates
+ name: Requirement Spec Templates
+ order: 800
+ access: requirement_spec_edit
+ params:
+ action: RequirementSpec/list
+ is_template: 1
+- id: ar
+ name: AR
+ icon: ar
+ order: 200
+- parent: ar
+ id: ar_add_requirement_spec
+ name: Add Requirement Spec
+ order: 100
+ access: requirement_spec_edit
+ params:
+ action: RequirementSpec/new
+- parent: ar
+ id: ar_add_quotation
+ name: Add Quotation
+ icon: quotation_add
+ order: 200
+ access: sales_quotation_edit
+ module: oe.pl
+ params:
+ action: add
+ type: sales_quotation
+- parent: ar
+ id: ar_add_sales_order
+ name: Add Sales Order
+ icon: sales_order_add
+ order: 300
+ access: sales_order_edit
+ module: oe.pl
+ params:
+ action: add
+ type: sales_order
+- parent: ar
+ id: ar_add_delivery_order
+ name: Add Delivery Order
+ icon: delivery_order_add
+ order: 400
+ access: sales_delivery_order_edit
+ module: do.pl
+ params:
+ action: add
+ type: sales_delivery_order
+- parent: ar
+ id: ar_add_sales_invoice
+ name: Add Sales Invoice
+ icon: sales_invoice_add
+ order: 500
+ access: invoice_edit
+ module: is.pl
+ params:
+ action: add
+ type: invoice
+- parent: ar
+ id: ar_add_credit_note
+ name: Add Credit Note
+ icon: credit_note_add
+ order: 600
+ access: invoice_edit
+ module: is.pl
+ params:
+ action: add
+ type: credit_note
+- parent: ar
+ id: ar_add_dunning
+ name: Add Dunning
+ icon: dunning_add
+ order: 700
+ access: dunning_edit
+ module: dn.pl
+ params:
+ action: add
+- parent: ar
+ id: ar_add_letter
+ name: Add Letter
+ order: 800
+ access: sales_letter_edit
+ module: letter.pl
+ params:
+ action: add
+- parent: ar
+ id: ar_reports
+ name: Reports
+ icon: ar_report
+ order: 900
+- parent: ar_reports
+ id: ar_reports_requirement_specs
+ name: Requirement Specs
+ order: 100
+ access: requirement_spec_edit
+ params:
+ action: RequirementSpec/list
+- parent: ar_reports
+ id: ar_reports_quotations
+ name: Quotations
+ icon: report_quotations
+ order: 200
+ access: sales_quotation_edit
+ module: oe.pl
+ params:
+ action: search
+ type: sales_quotation
+- parent: ar_reports
+ id: ar_reports_sales_orders
+ name: Sales Orders
+ icon: report_sales_orders
+ order: 300
+ access: sales_order_edit
+ module: oe.pl
+ params:
+ action: search
+ type: sales_order
+- parent: ar_reports
+ id: ar_reports_delivery_orders
+ name: Delivery Orders
+ icon: delivery_order_report
+ order: 400
+ access: sales_delivery_order_edit
+ module: do.pl
+ params:
+ action: search
+ type: sales_delivery_order
+- parent: ar_reports
+ id: ar_reports_invoices_credit_notes_ar_transactions
+ name: Invoices, Credit Notes & AR Transactions
+ icon: invoices_report
+ order: 500
+ access: invoice_edit
+ module: ar.pl
+ params:
+ action: search
+ nextsub: ar_transactions
+- parent: ar_reports
+ id: ar_reports_sales_report
+ name: Sales Report
+ order: 600
+ access: invoice_edit
+ module: vk.pl
+ params:
+ action: search_invoice
+ nextsub: invoice_transactions
+- parent: ar_reports
+ id: ar_reports_dunnings
+ name: Dunnings
+ icon: dunnings_report
+ order: 700
+ access: dunning_edit
+ module: dn.pl
+ params:
+ action: search
+- parent: ar_reports
+ id: ar_reports_delivery_plan
+ name: Delivery Plan
+ order: 800
+ access: delivery_plan
+ params:
+ action: DeliveryPlan/list
+ vc: customer
+ mode: delivery_plan
+- parent: ar_reports
+ id: ar_reports_delivery_value_report
+ name: Delivery Value Report
+ order: 900
+ access: delivery_value_report
+ params:
+ action: DeliveryPlan/list
+ mode: delivery_value_report
+ vc: customer
+- parent: ar_reports
+ id: ar_reports_financial_controlling
+ name: Financial Controlling
+ order: 1000
+ access: sales_order_edit
+ params:
+ action: FinancialControllingReport/list
+- parent: ar_reports
+ id: ar_reports_letters
+ name: Letters
+ order: 1100
+ access: sales_letter_report
+ module: letter.pl
+ params:
+ action: search
+- id: ap
+ name: AP
+ icon: ap
+ order: 300
+- parent: ap
+ id: ap_add_rfq
+ name: Add RFQ
+ icon: rfq_add
+ order: 100
+ access: request_quotation_edit
+ module: oe.pl
+ params:
+ action: add
+ type: request_quotation
+- parent: ap
+ id: ap_add_purchase_order
+ name: Add Purchase Order
+ icon: purchase_order_add
+ order: 200
+ access: purchase_order_edit
+ module: oe.pl
+ params:
+ action: add
+ type: purchase_order
+- parent: ap
+ id: ap_add_delivery_note
+ name: Add Delivery Note
+ order: 300
+ access: client/allow_new_purchase_delivery_order & purchase_delivery_order_edit
+ module: do.pl
+ params:
+ action: add
+ type: purchase_delivery_order
+- parent: ap
+ id: ap_add_vendor_invoice
+ name: Add Vendor Invoice
+ order: 400
+ access: client/allow_new_purchase_invoice & vendor_invoice_edit
+ module: ir.pl
+ params:
+ action: add
+ type: invoice
+- parent: ap
+ id: ap_reports
+ name: Reports
+ icon: ap_report
+ order: 500
+- parent: ap_reports
+ id: ap_reports_rfqs
+ name: RFQs
+ icon: rfq_report
+ order: 100
+ access: request_quotation_edit
+ module: oe.pl
+ params:
+ action: search
+ type: request_quotation
+- parent: ap_reports
+ id: ap_reports_purchase_orders
+ name: Purchase Orders
+ icon: purchase_order_report
+ order: 200
+ access: purchase_order_edit
+ module: oe.pl
+ params:
+ action: search
+ type: purchase_order
+- parent: ap_reports
+ id: ap_reports_delivery_orders
+ name: Delivery Orders
+ order: 300
+ access: purchase_delivery_order_edit
+ module: do.pl
+ params:
+ action: search
+ type: purchase_delivery_order
+- parent: ap_reports
+ id: ap_reports_vendor_invoices_ap_transactions
+ name: Vendor Invoices & AP Transactions
+ order: 400
+ access: vendor_invoice_edit
+ module: ap.pl
+ params:
+ action: search
+ nextsub: ap_transactions
+- parent: ap_reports
+ id: ap_reports_delivery_plan
+ name: Delivery Plan
+ order: 500
+ access: delivery_plan
+ params:
+ action: DeliveryPlan/list
+ mode: delivery_plan
+ vc: vendor
+- parent: ap_reports
+ id: ap_reports_delivery_value_report
+ name: Delivery Value Report
+ order: 600
+ access: delivery_value_report
+ params:
+ action: DeliveryPlan/list
+ vc: vendor
+ mode: delivery_value_report
+- id: warehouse
+ name: Warehouse
+ icon: warehouse
+ order: 400
+- parent: warehouse
+ id: warehouse_stock
+ name: Stock
+ order: 100
+ access: warehouse_management
+ params:
+ action: Inventory/stock_in
+- parent: warehouse
+ id: warehouse_produce_assembly
+ name: Produce Assembly
+ icon: assembly_produce
+ order: 200
+ access: warehouse_management
+ module: wh.pl
+ params:
+ action: transfer_warehouse_selection
+ trans_type: assembly
+- parent: warehouse
+ id: warehouse_transfer
+ name: Transfer
+ order: 300
+ access: warehouse_management
+ module: wh.pl
+ params:
+ action: transfer_warehouse_selection
+ trans_type: transfer
+- parent: warehouse
+ id: warehouse_removal
+ name: Removal
+ order: 400
+ access: warehouse_management
+ module: wh.pl
+ params:
+ action: transfer_warehouse_selection
+ trans_type: removal
+- parent: warehouse
+ id: warehouse_reports
+ name: Reports
+ order: 500
+- parent: warehouse_reports
+ id: warehouse_reports_warehouse_content
+ name: Warehouse content
+ order: 100
+ access: warehouse_contents | warehouse_management
+ module: wh.pl
+ params:
+ action: report
+- parent: warehouse_reports
+ id: warehouse_reports_whjournal
+ name: WHJournal
+ order: 200
+ access: warehouse_management
+ module: wh.pl
+ params:
+ action: journal
+- id: general_ledger
+ name: General Ledger
+ icon: gl
+ order: 500
+- parent: general_ledger
+ id: general_ledger_add_transaction
+ name: Add Transaction
+ icon: transaction_add
+ order: 100
+ access: general_ledger
+ module: gl.pl
+ params:
+ action: add
+- parent: general_ledger
+ id: general_ledger_add_ar_transaction
+ name: Add AR Transaction
+ icon: ar_transaction_add
+ order: 200
+ access: general_ledger
+ module: ar.pl
+ params:
+ action: add
+- parent: general_ledger
+ id: general_ledger_add_ap_transaction
+ name: Add AP Transaction
+ icon: ap_transaction_add
+ order: 300
+ access: general_ledger
+ module: ap.pl
+ params:
+ action: add
+- parent: general_ledger
+ id: general_ledger_datev_export_assistent
+ name: DATEV - Export Assistent
+ icon: datev
+ order: 400
+ access: datev_export
+ module: datev.pl
+ params:
+ action: export
+- parent: general_ledger
+ id: general_ledger_reports
+ name: Reports
+ icon: gl_report
+ order: 500
+- parent: general_ledger_reports
+ id: general_ledger_reports_ar_aging
+ name: AR Aging
+ icon: ar_aging
+ order: 100
+ access: general_ledger
+ module: rp.pl
+ params:
+ action: report
+ report: ar_aging
+- parent: general_ledger_reports
+ id: general_ledger_reports_ap_aging
+ name: AP Aging
+ icon: ap_aging
+ order: 200
+ access: general_ledger
+ module: rp.pl
+ params:
+ action: report
+ report: ap_aging
+- parent: general_ledger_reports
+ id: general_ledger_reports_journal
+ name: Journal
+ icon: journal
+ order: 300
+ access: general_ledger
+ module: gl.pl
+ params:
+ action: search
+- id: cash
+ name: Cash
+ icon: cash
+ order: 600
+- parent: cash
+ id: cash_receipt
+ name: Receipt
+ icon: receipt
+ order: 100
+ access: cash
+ module: cp.pl
+ params:
+ action: payment
+ vc: customer
+ type: receipt
+- parent: cash
+ id: cash_payment
+ name: Payment
+ icon: payment
+ order: 200
+ access: cash
+ module: cp.pl
+ params:
+ action: payment
+ vc: vendor
+ type: check
+- parent: cash
+ id: cash_bank_collection_via_sepa
+ name: Bank collection via SEPA
+ order: 300
+ access: cash
+ module: sepa.pl
+ params:
+ action: bank_transfer_add
+ vc: customer
+- parent: cash
+ id: cash_bank_transfer_via_sepa
+ name: Bank transfer via SEPA
+ order: 400
+ access: cash
+ module: sepa.pl
+ params:
+ action: bank_transfer_add
+ vc: vendor
+- parent: cash
+ id: cash_bank_import
+ name: Bank Import
+ order: 500
+- parent: cash_bank_import
+ id: cash_bank_import_csv
+ name: CSV
+ order: 100
+ access: bank_transaction
+ params:
+ action: CsvImport/new
+ profile.type: bank_transactions
+- parent: cash_bank_import
+ id: cash_bank_import_mt940
+ name: MT940
+ order: 200
+ access: bank_transaction
+ params:
+ action: BankImport/upload_mt940
+- parent: cash
+ id: cash_bank_transactions_mt940
+ name: Bank transactions MT940
+ order: 600
+ access: bank_transaction
+ params:
+ action: BankTransaction/search
+- parent: cash
+ id: cash_reconciliation_with_bank
+ name: Reconciliation with bank
+ order: 700
+ access: bank_transaction
+ params:
+ action: Reconciliation/search
+ next_sub: Reconciliation/reconciliation
+- parent: cash
+ id: cash_reconciliation
+ name: Reconciliation
+ icon: reconcilliation
+ order: 800
+ access: cash
+ module: rc.pl
+ params:
+ action: reconciliation
+- parent: cash
+ id: cash_reports
+ name: Reports
+ icon: cash_report
+ order: 900
+- parent: cash_reports
+ id: cash_reports_receipts
+ name: Receipts
+ icon: receipt_report
+ order: 100
+ access: cash
+ module: rp.pl
+ params:
+ action: report
+ report: receipts
+- parent: cash_reports
+ id: cash_reports_payments
+ name: Payments
+ icon: payment_report
+ order: 200
+ access: cash
+ module: rp.pl
+ params:
+ action: report
+ report: payments
+- parent: cash_reports
+ id: cash_reports_bank_collections_via_sepa
+ name: Bank collections via SEPA
+ order: 300
+ access: cash
+ module: sepa.pl
+ params:
+ action: bank_transfer_search
+ vc: customer
+- parent: cash_reports
+ id: cash_reports_bank_transfers_via_sepa
+ name: Bank transfers via SEPA
+ order: 400
+ access: cash
+ module: sepa.pl
+ params:
+ action: bank_transfer_search
+ vc: vendor
+- parent: cash_reports
+ id: cash_reports_bank_transactions
+ name: Bank transactions
+ order: 500
+ access: bank_transaction
+ params:
+ action: BankTransaction/list_all
+- id: reports
+ name: Reports
+ icon: report
+ order: 700
+- parent: reports
+ id: reports_chart_of_accounts
+ name: Chart of Accounts
+ icon: chart_of_accounts
+ order: 100
+ access: report
+ module: ca.pl
+ params:
+ action: chart_of_accounts
+- parent: reports
+ id: reports_trial_balance
+ name: Trial Balance
+ order: 200
+ access: report
+ module: rp.pl
+ params:
+ action: report
+ report: trial_balance
+- parent: reports
+ id: reports_income_statement
+ name: Income Statement
+ icon: income_statement
+ order: 300
+ access: report
+ module: rp.pl
+ params:
+ action: report
+ report: income_statement
+- parent: reports
+ id: reports_bwa
+ name: BWA
+ order: 400
+ access: report
+ module: rp.pl
+ params:
+ action: report
+ report: bwa
+- parent: reports
+ id: reports_balance_sheet
+ name: Balance Sheet
+ icon: balance_sheet
+ order: 500
+ access: report
+ module: rp.pl
+ params:
+ action: report
+ report: balance_sheet
+- parent: reports
+ id: reports_ustva
+ name: UStVa
+ icon: ustva
+ order: 600
+ access: advance_turnover_tax_return
+ module: ustva.pl
+ params:
+ action: report
+- parent: reports
+ id: reports_projecttransactions
+ name: Projecttransactions
+ order: 700
+ access: report
+ module: rp.pl
+ params:
+ action: report
+ report: projects
+- parent: reports
+ id: reports_financial_overview
+ name: Financial Overview
+ order: 800
+ access: report
+ params:
+ action: FinancialOverview/list
+- parent: reports
+ id: reports_liquidity_projection
+ name: Liquidity projection
+ order: 900
+ access: report
+ params:
+ action: LiquidityProjection/show
+- id: batch_printing
+ name: Batch Printing
+ icon: printing
+ order: 800
+ access: batch_printing
+- parent: batch_printing
+ id: batch_printing_sales_invoices
+ name: Sales Invoices
+ icon: sales_invoice_printing
+ order: 100
+ access: invoice_edit
+ module: bp.pl
+ params:
+ action: search
+ vc: customer
+ type: invoice
+- parent: batch_printing
+ id: batch_printing_sales_orders
+ name: Sales Orders
+ icon: sales_order_printing
+ order: 200
+ access: sales_order_edit
+ module: bp.pl
+ params:
+ action: search
+ type: sales_order
+ vc: customer
+- parent: batch_printing
+ id: batch_printing_quotations
+ name: Quotations
+ icon: quotation_printing
+ order: 300
+ access: sales_quotation_edit
+ module: bp.pl
+ params:
+ action: search
+ vc: customer
+ type: sales_quotation
+- parent: batch_printing
+ id: batch_printing_packing_lists
+ name: Packing Lists
+ icon: package_lists
+ order: 400
+ access: invoice_edit | sales_order_edit
+ module: bp.pl
+ params:
+ action: search
+ type: packing_list
+ vc: customer
+- parent: batch_printing
+ id: batch_printing_purchase_orders
+ name: Purchase Orders
+ icon: purchase_order_printing
+ order: 500
+ access: purchase_order_edit
+ module: bp.pl
+ params:
+ action: search
+ type: purchase_order
+ vc: vendor
+- parent: batch_printing
+ id: batch_printing_rfqs
+ name: RFQs
+ icon: rfq_printing
+ order: 600
+ access: request_quotation_edit
+ module: bp.pl
+ params:
+ action: search
+ vc: vendor
+ type: request_quotation
+- parent: batch_printing
+ id: batch_printing_checks
+ name: Checks
+ order: 700
+ access: cash
+ module: bp.pl
+ params:
+ action: search
+ type: check
+ vc: vendor
+- parent: batch_printing
+ id: batch_printing_receipts
+ name: Receipts
+ icon: receipt_printing
+ order: 800
+ access: cash
+ module: bp.pl
+ params:
+ action: search
+ vc: customer
+ type: receipt
+- id: productivity
+ name: Productivity
+ icon: productivity
+ order: 900
+ access: productivity
+- parent: productivity
+ id: productivity_show_todo_list
+ name: Show TODO list
+ order: 100
+ module: todo.pl
+ params:
+ action: show_todo_list
+- parent: productivity
+ id: productivity_add_follow_up
+ name: Add Follow-Up
+ order: 200
+ module: fu.pl
+ params:
+ action: add
+- parent: productivity
+ id: productivity_edit_access_rights
+ name: Edit Access Rights
+ order: 300
+ module: fu.pl
+ params:
+ action: edit_access_rights
+- parent: productivity
+ id: productivity_reports
+ name: Reports
+ order: 400
+- parent: productivity_reports
+ id: productivity_reports_follow_ups
+ name: Follow-Ups
+ order: 100
+ module: fu.pl
+ params:
+ action: search
+- id: system
+ name: System
+ icon: system
+ order: 1000
+ access: config
+- parent: system
+ id: system_client_configuration
+ name: Client Configuration
+ order: 100
+ access: admin
+ params:
+ action: ClientConfig/edit
+- parent: system
+ id: system_ustva_einstellungen
+ name: UStVa Einstellungen
+ order: 200
+ module: ustva.pl
+ params:
+ action: config_step1
+- parent: system
+ id: system_edit_dunning
+ name: Edit Dunning
+ order: 300
+ module: dn.pl
+ params:
+ action: edit_config
+- parent: system
+ id: system_chart_of_accounts
+ name: Chart of Accounts
+ order: 400
+- parent: system_chart_of_accounts
+ id: system_chart_of_accounts_add_account
+ name: Add Account
+ order: 100
+ module: am.pl
+ params:
+ action: add_account
+- parent: system_chart_of_accounts
+ id: system_chart_of_accounts_list_accounts
+ name: List Accounts
+ order: 200
+ module: am.pl
+ params:
+ action: list_account
+- parent: system
+ id: system_buchungsgruppen
+ name: Buchungsgruppen
+ order: 500
+ params:
+ action: Buchungsgruppen/list
+- parent: system
+ id: system_taxzones
+ name: Taxzones
+ order: 600
+ params:
+ action: Taxzones/list
+- parent: system
+ id: system_taxes
+ name: Taxes
+ order: 700
+ module: am.pl
+ params:
+ action: list_tax
+- parent: system
+ id: system_bank_accounts
+ name: Bank accounts
+ order: 800
+ params:
+ action: BankAccount/list
+- parent: system
+ id: system_groups
+ name: Groups
+ order: 900
+ module: pe.pl
+ params:
+ action: search
+ type: partsgroup
+- parent: system
+ id: system_pricegroups
+ name: Pricegroups
+ order: 1000
+ module: pe.pl
+ params:
+ action: search
+ type: pricegroup
+- parent: system
+ id: system_edit_units
+ name: Edit units
+ order: 1100
+ module: am.pl
+ params:
+ action: edit_units
+- parent: system
+ id: system_price_factors
+ name: Price Factors
+ order: 1200
+ module: am.pl
+ params:
+ action: list_price_factors
+- parent: system
+ id: system_departments
+ name: Departments
+ order: 1300
+ params:
+ action: Department/list
+- parent: system
+ id: system_types_of_business
+ name: Types of Business
+ order: 1400
+ params:
+ action: Business/list
+- parent: system
+ id: system_leads
+ name: Leads
+ order: 1500
+ module: am.pl
+ params:
+ action: list_lead
+- parent: system
+ id: system_project_types
+ name: Project Types
+ order: 1600
+ params:
+ action: ProjectType/list
+- parent: system
+ id: system_project_status
+ name: Project Status
+ order: 1700
+ params:
+ action: ProjectStatus/list
+- parent: system
+ id: system_requirement_specs
+ name: Requirement specs
+ order: 1800
+- parent: system_requirement_specs
+ id: system_requirement_specs_pre_defined_texts
+ name: Pre-defined Texts
+ order: 100
+ params:
+ action: RequirementSpecPredefinedText/list
+- parent: system_requirement_specs
+ id: system_requirement_specs_requirement_spec_types
+ name: Requirement Spec Types
+ order: 200
+ params:
+ action: RequirementSpecType/list
+- parent: system_requirement_specs
+ id: system_requirement_specs_requirement_spec_statuses
+ name: Requirement Spec Statuses
+ order: 300
+ params:
+ action: RequirementSpecStatus/list
+- parent: system_requirement_specs
+ id: system_requirement_specs_complexities
+ name: Complexities
+ order: 400
+ params:
+ action: RequirementSpecComplexity/list
+- parent: system_requirement_specs
+ id: system_requirement_specs_risks
+ name: Risks
+ order: 500
+ params:
+ action: RequirementSpecRisk/list
+- parent: system_requirement_specs
+ id: system_requirement_specs_acceptance_statuses
+ name: Acceptance Statuses
+ order: 600
+ params:
+ action: RequirementSpecAcceptanceStatus/list
+- parent: system
+ id: system_languages_and_translations
+ name: Languages and translations
+ order: 1900
+- parent: system_languages_and_translations
+ id: system_languages_and_translations_add_language
+ name: Add Language
+ order: 100
+ module: am.pl
+ params:
+ action: add_language
+- parent: system_languages_and_translations
+ id: system_languages_and_translations_list_languages
+ name: List Languages
+ order: 200
+ module: am.pl
+ params:
+ action: list_language
+- parent: system_languages_and_translations
+ id: system_languages_and_translations_greetings
+ name: Greetings
+ order: 300
+ module: generictranslations.pl
+ params:
+ action: edit_greetings
+- parent: system_languages_and_translations
+ id: system_languages_and_translations_sepa_strings
+ name: SEPA strings
+ order: 400
+ module: generictranslations.pl
+ params:
+ action: edit_sepa_strings
+- parent: system
+ id: system_payment_terms
+ name: Payment Terms
+ order: 2000
+ params:
+ action: PaymentTerm/list
+- parent: system
+ id: system_delivery_terms
+ name: Delivery Terms
+ order: 2100
+ params:
+ action: DeliveryTerm/list
+- parent: system
+ id: system_manage_custom_variables
+ name: Manage Custom Variables
+ order: 2200
+ params:
+ action: CustomVariableConfig/list
+- parent: system
+ id: system_warehouses
+ name: Warehouses
+ order: 2300
+ module: am.pl
+ params:
+ action: list_warehouses
+- parent: system
+ id: system_import_csv
+ name: Import CSV
+ order: 2400
+- parent: system_import_csv
+ id: system_import_csv_customers_and_vendors
+ name: Customers and vendors
+ order: 100
+ params:
+ action: CsvImport/new
+ profile.type: customers_vendors
+- parent: system_import_csv
+ id: system_import_csv_contacts
+ name: Contacts
+ order: 200
+ params:
+ action: CsvImport/new
+ profile.type: contacts
+- parent: system_import_csv
+ id: system_import_csv_shipto
+ name: Shipto
+ order: 300
+ params:
+ action: CsvImport/new
+ profile.type: addresses
+- parent: system_import_csv
+ id: system_import_csv_parts
+ name: Parts
+ order: 400
+ params:
+ action: CsvImport/new
+ profile.type: parts
+- parent: system_import_csv
+ id: system_import_csv_inventories
+ name: Inventories
+ order: 500
+ params:
+ action: CsvImport/new
+ profile.type: inventories
+- parent: system_import_csv
+ id: system_import_csv_projects
+ name: Projects
+ order: 600
+ params:
+ action: CsvImport/new
+ profile.type: projects
+- parent: system_import_csv
+ id: system_import_csv_orders
+ name: Orders
+ order: 700
+ params:
+ action: CsvImport/new
+ profile.type: orders
+- parent: system
+ id: system_templates
+ name: Templates
+ order: 2500
+ access: admin
+- parent: system_templates
+ id: system_templates_html_templates
+ name: HTML Templates
+ order: 100
+ module: amtemplates.pl
+ params:
+ action: display_template_form
+ type: templates
+ format: html
+- parent: system_templates
+ id: system_templates_latex_templates
+ name: LaTeX Templates
+ order: 200
+ module: amtemplates.pl
+ params:
+ action: display_template_form
+ format: tex
+ type: templates
+- parent: system_templates
+ id: system_templates_stylesheet
+ name: Stylesheet
+ order: 300
+ module: amtemplates.pl
+ params:
+ action: display_template_form
+ type: stylesheet
+- parent: system
+ id: system_general_ledger_corrections
+ name: General Ledger Corrections
+ order: 2600
+ module: acctranscorrections.pl
+ params:
+ action: analyze_filter
+- parent: system
+ id: system_background_jobs_and_task_server
+ name: Background jobs and task server
+ order: 2700
+ access: admin
+- parent: system_background_jobs_and_task_server
+ id: system_background_jobs_and_task_server_list_current_background_jobs
+ name: List current background jobs
+ order: 100
+ params:
+ action: BackgroundJob/list
+- parent: system_background_jobs_and_task_server
+ id: system_background_jobs_and_task_server_background_job_history
+ name: Background job history
+ order: 200
+ params:
+ action: BackgroundJobHistory/list
+- parent: system_background_jobs_and_task_server
+ id: system_background_jobs_and_task_server_task_server_control
+ name: Task server control
+ order: 300
+ params:
+ action: TaskServer/show
+- parent: system
+ id: system_audit_control
+ name: Audit Control
+ order: 2800
+ module: am.pl
+ params:
+ action: audit_control
+- parent: system
+ id: system_history_search_engine
+ name: History Search Engine
+ order: 2900
+ module: am.pl
+ params:
+ action: show_history_search
+- parent: system
+ id: system_employees
+ name: Employees
+ order: 3000
+ access: admin
+ params:
+ action: Employee/list
+- id: program
+ name: Program
+ icon: program
+ order: 1100
+- parent: program
+ id: program_user_preferences
+ name: User Preferences
+ order: 100
+ module: am.pl
+ params:
+ action: config
+- parent: program
+ id: program_internal_phone_list
+ name: Internal Phone List
+ order: 200
+ params:
+ action: CTI/list_internal_extensions
+- parent: program
+ id: program_version
+ name: Version
+ icon: version
+ order: 300
+ module: login.pl
+ params:
+ action: company_logo
+ no_todo_list: 1
+- parent: program
+ id: program_administration_area
+ name: Administration area
+ order: 400
+ access: display_admin_link
+ params:
+ action: Admin/login
+- parent: program
+ id: program_documentation_in_german_
+ name: Documentation (in German)
+ order: 500
+ href: doc/kivitendo-Dokumentation.pdf
+ target: _blank
+- parent: program
+ id: program_kivitendo_website_external_
+ name: kivitendo website (external)
+ order: 600
+ href: http://www.kivitendo.de/
+ target: _blank
+- parent: program
+ id: program_logout
+ name: Logout
+ icon: logout
+ order: 700
+ params:
+ action: LoginScreen/logout
--- /dev/null
+---
+- id: crm
+ name: CRM
+ icon: crm
+ order: 50
+- parent: crm
+ id: crm_search
+ name: Search
+ icon: search
+ order: 100
+ access: crm_search
+ module: crm/getData.php
+- parent: crm
+ id: crm_add
+ name: Add
+ order: 200
+- parent: crm_add
+ id: crm_add_customer
+ name: Customer
+ icon: customer
+ order: 100
+ access: crm_new
+ module: crm/firmen3.php
+ params:
+ Q: C
+- parent: crm_add
+ id: crm_add_vendor
+ name: Vendor
+ icon: vendor
+ order: 200
+ access: crm_new
+ module: crm/firmen3.php
+ params:
+ Q: V
+- parent: crm_add
+ id: crm_add_person
+ name: Person
+ icon: contact
+ order: 300
+ access: crm_new
+ module: crm/personen3.php
+- parent: crm
+ id: crm_appointments
+ name: Appointments
+ icon: appointment
+ order: 300
+ access: crm_termin
+ module: crm/termin.php
+- parent: crm
+ id: crm_opportunity
+ name: Opportunity
+ icon: opportunity
+ order: 400
+ access: crm_opportunity
+ module: crm/opportunity.php
+- parent: crm
+ id: crm_follow_up
+ name: Follow-Up
+ icon: follow_up
+ order: 500
+ access: crm_follow
+ module: crm/wvl1.php
+- parent: crm
+ id: crm_e_mail
+ name: E-mail
+ icon: email
+ order: 600
+ access: crm_email
+ module: crm/mail.php
+- parent: crm
+ id: crm_knowledge
+ name: Knowledge
+ icon: knowledge
+ order: 700
+ access: crm_knowhow
+ module: crm/wissen.php
+- parent: crm
+ id: crm_memo
+ name: Memo
+ icon: memo
+ order: 800
+ access: crm_notices
+ module: crm/postit.php
+- parent: crm
+ id: crm_documents
+ name: Documents
+ order: 900
+ access: crm_other
+ module: crm/dokument.php
+- parent: crm
+ id: crm_time_tracking
+ name: Time Tracking
+ order: 1000
+ access: crm_service
+ module: crm/timetrack.php
+- parent: crm
+ id: crm_other
+ name: Other
+ order: 1100
+- parent: crm_other
+ id: crm_other_etikett
+ name: Etikett
+ order: 100
+ access: crm_other
+ module: crm/prtetikett.php
+ target: _blank
+- parent: crm_other
+ id: crm_other_dhl
+ name: DHL
+ order: 200
+ access: crm_other
+ module: crm/dhl.php
+- parent: crm_other
+ id: crm_other_ebayimporter
+ name: eBayImporter
+ order: 300
+ access: crm_other
+ module: crm/ebayImporter.php
+- parent: crm_other
+ id: crm_other_catalog
+ name: Catalog
+ order: 400
+ access: crm_other
+ module: crm/katalog.php
+- parent: crm_other
+ id: crm_other_warehouse_list
+ name: Warehouse list
+ order: 500
+ access: crm_other
+ module: crm/inventur.php
+- parent: crm_other
+ id: crm_other_warehouse_correction
+ name: Warehouse correction
+ order: 600
+ access: crm_admin
+ module: crm/inventurlager.php
+- parent: crm_other
+ id: crm_other_partsedit
+ name: Partsedit
+ order: 700
+ access: crm_other
+ module: crm/partsedit.php
+- parent: crm_other
+ id: crm_other_packliste
+ name: Packliste
+ order: 800
+ access: crm_other
+ module: crm/packliste.php
+- parent: crm_other
+ id: crm_other_eur
+ name: EuR
+ order: 900
+ access: crm_other
+ module: crm/eur.php
+- parent: crm_other
+ id: crm_other_zm
+ name: ZM
+ order: 1000
+ access: crm_other
+ module: crm/ustva_zm.php
+- parent: crm
+ id: crm_service
+ name: Service
+ icon: service
+ order: 1200
+- parent: crm_service
+ id: crm_service_service_contract
+ name: Service Contract
+ order: 100
+ access: crm_service
+ module: crm/vertrag1.php
+- parent: crm_service
+ id: crm_service_add_service_contract
+ name: Add Service Contract
+ order: 200
+ access: crm_service
+ module: crm/vertrag3.php
+- parent: crm_service
+ id: crm_service_machine
+ name: Machine
+ order: 300
+ access: crm_service
+ module: crm/maschine1.php
+- parent: crm_service
+ id: crm_service_add_machine
+ name: Add Machine
+ order: 400
+ access: crm_service
+ module: crm/maschine3.php
+- parent: crm
+ id: crm_admin
+ name: Admin
+ icon: admin
+ order: 1300
+- parent: crm_admin
+ id: crm_admin_document_template
+ name: Document Template
+ icon: document_template
+ order: 100
+ access: crm_admin
+ module: crm/dokument1.php
+- parent: crm_admin
+ id: crm_admin_label
+ name: Label
+ icon: label
+ order: 200
+ access: crm_admin
+ module: crm/aufkleber_def.php
+- parent: crm_admin
+ id: crm_admin_appointment_category
+ name: Appointment Category
+ order: 300
+ access: crm_admin
+ module: crm/tcatedit.php
+- parent: crm_admin
+ id: crm_admin_message
+ name: Message
+ icon: message
+ order: 400
+ access: crm_admin
+ module: crm/user3.php
+- parent: crm_admin
+ id: crm_admin_client
+ name: Client
+ order: 500
+ access: crm_adminstatus
+ module: crm/mandant.php
+- parent: crm_admin
+ id: crm_admin_user_groups
+ name: User Groups
+ icon: user_group
+ order: 600
+ access: crm_admin
+ module: crm/user2.php
+- parent: crm_admin
+ id: crm_admin_user
+ name: User
+ icon: user
+ order: 700
+ access: crm_adminuser
+ module: crm/user1.php
+- parent: crm_admin
+ id: crm_admin_dhl
+ name: DHL
+ order: 800
+ access: crm_adminuser
+ module: crm/dhladm.php
+- parent: crm_admin
+ id: crm_admin_status
+ name: Status
+ icon: status
+ order: 900
+ access: crm_adminstatus
+ module: crm/status.php
#!/usr/bin/perl
use strict;
-use GD;
use Getopt::Long;
use File::Basename;
-
my $css_file = 'generated.css';
my $image_file = 'generated.png';
my $class_for_map = 'icon';
+my $convert_bin = 'convert';
+my $identify_bin = 'identify';
+
GetOptions(
'css-out=s' => \$css_file,
'image-out=s' => \$image_file,
);
my @files = @ARGV;
-my @gd_images;
-
-GD::Image->trueColor(1);
+my @images;
# read files
-for my $filename (@files) {
- my $image = GD::Image->newFromPng($filename);
+for my $filename (sort @files) {
+ my $image = `$identify_bin $filename`;
if (!defined $image) {
- warn "warning: could not load image '$filename'. skpping...";
+ warn "warning: could not identify image '$filename'. skpping...";
next;
}
- push @gd_images, {
- gd => $image,
+ $image =~ /^(?<filename>\S+) \s (?<type>\S+) \s (?<width>\d+) x (?<height>\d+)/x;
+ push @images, {
filename => $filename,
+ type => $+{type},
+ width => $+{width},
+ height => $+{height},
};
}
# make target layout
# for simplification thi will check if all the images have the same dimensions
# and croak if not
-my $first_height = $gd_images[0]->{gd}->height;
-my $first_width = $gd_images[0]->{gd}->width;
+my $first_height = $images[0]->{height};
+my $first_width = $images[0]->{width};
use Data::Dumper;
-for my $img (@gd_images) {
- die 'heights are not equal' if $first_height != $img->{gd}->height;
- die 'widths are not equal' if $first_width != $img->{gd}->width;
+for my $img (@images) {
+ die 'heights are not equal' if $first_height != $img->{height};
+ die 'widths are not equal' if $first_width != $img->{width};
}
# all equal? nice.
# we'll be lazy and just put them all together left-to-right
my $new_height = $first_height;
-my $new_width = $first_width * @gd_images;
+my $new_width = $first_width * @images;
-my $new_image = GD::Image->new($new_width, $new_height, 1);
# now copy them all together, and keep a referende to;
-$new_image->saveAlpha(1);
-$new_image->alphaBlending(0);
+my $convert_string = "$convert_bin ";
my $h_offset = 0;
-for (@gd_images) {
+for (@images) {
$_->{h_offset} = $h_offset;
$_->{v_offset} = 0;
- $new_image->copy($_->{gd}, $_->{h_offset}, $_->{v_offset}, 0, 0, $_->{gd}->width, $_->{gd}->height);
+ $convert_string .= ' +append ' . $_->{filename};
} continue {
- $h_offset += $_->{gd}->width;
+ $h_offset += $_->{width};
}
+$convert_string .= " -background none +append $image_file";
+
# now write that png...
-{
- open my $file, '>:raw', $image_file or die "can't write to $image_file";
- print $file $new_image->png;
-}
+system($convert_string);
# make css file
{
open my $file, ">", $css_file or die "can't write too $css_file";
print $file ".$class_for_map { background: url(../$image_file) ${first_width}px 0px no-repeat; padding: 0; width: ${first_width}px; height: ${first_height}px; }\n";
- for (@gd_images) {
+ for (@images) {
my $name = fileparse($_->{filename}, ".png");
# the full grammar for valid css class names is completely bonkers (to put it mildly).
use List::MoreUtils qw(apply);
use List::Util qw(first);
use Pod::Usage;
+use YAML ();
+use YAML::Loader (); # YAML tries to load Y:L at runtime, but can't find it after we chdir'ed
+use SL::DBUpgrade2;
$OUTPUT_AUTOFLUSH = 1;
my $locales_dir = ".";
my $bindir = "$basedir/bin/mozilla";
my @progdirs = ( "$basedir/SL" );
-my @menufiles = <${basedir}/menus/*.ini>;
+my @menufiles = <"${basedir}/menus/*/*">;
my @javascript_dirs = ($basedir .'/js', $basedir .'/templates/webpages');
my $javascript_output_dir = $basedir .'/js';
my $submitsearch = qr/type\s*=\s*[\"\']?submit/i;
# put customized files into @customfiles
my %dir_h;
-if ($opt_n) {
- @customfiles = ();
-} else {
- tie %dir_h, 'IO::Dir', $basedir;
- push @menufiles, map { "$basedir/$_" } grep { /.*_menu.ini$/ } keys %dir_h;
-}
-
my @dbplfiles;
foreach my $sub_dir ("Pg-upgrade2", "Pg-upgrade2-auth") {
my $dir = "$basedir/sql/$sub_dir";
handle_file(@{ $_ }) for @progfiles;
handle_file(@{ $_ }) for @dbplfiles;
scanmenu($_) for @menufiles;
+scandbupgrades();
for my $file_name (grep { /\.(?:js|html)$/i } map({find_files($_)} @javascript_dirs)) {
scan_javascript_file($file_name);
sub scanmenu {
my $file = shift;
- my $fh = new FileHandle;
- open $fh, '<:encoding(utf8)', $file or die "$! : $file";
+ my $menu = YAML::LoadFile($file);
- my @a = grep m/^\[/, <$fh>;
- close($fh);
+ for my $node (@$menu) {
+ # possible for override files
+ next unless exists $node->{name};
+
+ $locale{$node->{name}} = 1;
+ $alllocales{$node->{name}} = 1;
+ $cached{$file}{all}{$node->{name}} = 1;
+ }
+}
- # strip []
- grep { s/(\[|\])//g } @a;
+sub scandbupgrades {
+ # we only need to do this for auth atm, because only auth scripts can include new rights, which are translateable
+ my $auth = 1;
- foreach my $item (@a) {
- my @b = split /--/, $item;
- foreach my $string (@b) {
- chomp $string;
+ my $dbu = SL::DBUpgrade2->new(auth => $auth, path => '../../sql/Pg-upgrade2-auth');
+
+ for my $upgrade ($dbu->sort_dbupdate_controls) {
+ for my $string (@{ $upgrade->{locales} || [] }) {
$locale{$string} = 1;
$alllocales{$string} = 1;
+ $cached{$upgrade->{tag}}{all}{$string} = 1;
}
}
-
}
sub unescape_template_string {
=head1 DESCRIPTION
-This script collects strings from Perl files, the menu.ini file and
+This script collects strings from Perl files, the menu files and
HTML templates and puts them into the file "all" for translation.
=cut
--- /dev/null
+
+use strict;
+use warnings;
+
+my %icons = (
+'AP--Add Purchase Order.png' => 'purchase_order_add.png',
+'AP--Add RFQ.png' => 'rfq_add.png',
+'AP.png' => 'ap.png',
+'AP--Reports.png' => 'ap_report.png',
+'AP--Reports--Purchase Orders.png' => 'purchase_order_report.png',
+'AP--Reports--RFQs.png' => 'rfq_report.png',
+'AR--Add Credit Note.png' => 'credit_note_add.png',
+'AR--Add Delivery Order.png' => 'delivery_oder_add.png', # symlink to MDI-Txt_editor
+'AR--Add Dunning.png' => 'dunning_add.png',
+'AR--Add Quotation.png' => 'quotation_add.png',
+'AR--Add Sales Invoice.png' => 'sales_invoice_add.png',
+'AR--Add Sales Order.png' => 'sales_order_add.png',
+'AR.png' => 'ar.png',
+'AR--Reports--Delivery Orders.png' => 'delivery_order_report.png', # symlink to MDI-Text_editor
+'AR--Reports--Dunnings.png' => 'dunnings_report.png',
+'AR--Reports--Invoices, Credit Notes & AR Transactions.png' => 'invoices_report.png',
+'AR--Reports.png' => 'ar_report.png',
+'AR--Reports--Quotations.png' => 'report_quotations.png',
+'AR--Reports--Sales Orders.png' => 'report_sales_orders.png',
+'Batch Printing--Packing Lists.png' => 'package_lists.png',
+'Batch Printing.png' => 'printing.png',
+'Batch Printing--Purchase Orders.png' => 'purchase_order_printing.png',
+'Batch Printing--Quotations.png' => 'quotation_printing.png',
+'Batch Printing--Receipts.png' => 'receipt_printing.png',
+'Batch Printing--RFQs.png' => 'rfq_printing.png',
+'Batch Printing--Sales Invoices.png' => 'sales_invoice_printing.png',
+'Batch Printing--Sales Orders.png' => 'sales_order_printing.png',
+'Cash--Payment.png' => 'payment.png',
+'Cash.png' => 'cash.png',
+'Cash--Receipt.png' => 'receipt.png',
+'Cash--Reconciliation.png' => 'reconcilliation.png',
+'Cash--Reports--Payments.png' => 'payment_report.png',
+'Cash--Reports.png' => 'cash_report.png',
+'Cash--Reports--Receipts.png' => 'receipt_report.png',
+'CRM--Add--Customer.png' => 'customer.png',
+'CRM--Add--Person.png' => 'contact.png',
+'CRM--Add--Vendor.png' => 'vendor.png',
+'CRM--Admin--Document Template.png' => 'document_template.png',
+'CRM--Admin--Label.png' => 'label.png',
+'CRM--Admin--Message.png' => 'message.png',
+'CRM--Admin.png' => 'admin.png',
+'CRM--Admin--Status.png' => 'status.png',
+'CRM--Admin--User Groups.png' => 'user_group.png',
+'CRM--Admin--User.png' => 'user.png',
+'CRM--Appointments.png' => 'appointment.png',
+'CRM--E-mail.png' => 'email.png',
+'CRM--Follow-Up.png' => 'follow_up.png',
+'CRM--Help.png' => 'help.png',
+'CRM--Knowledge.png' => 'knowledge.png',
+'CRM--Memo.png' => 'memo.png',
+'CRM--Opportunity.png' => 'opportunity.png',
+'CRM.png' => 'crm.png',
+'CRM--Search.png' => 'search.png',
+'CRM--Service.png' => 'service.png',
+'General Ledger--Add AP Transaction.png' => 'ap_transaction_add.png',
+'General Ledger--Add AR Transaction.png' => 'ar_transaction_add.png',
+'General Ledger--Add Transaction.png' => 'transaction_add.png',
+'General Ledger--DATEV - Export Assistent.png' => 'datev.png',
+'General Ledger.png' => 'gl.png',
+'General Ledger--Reports--AP Aging.png' => 'ap_aging.png',
+'General Ledger--Reports--AR Aging.png' => 'ar_aging.png',
+'General Ledger--Reports--Journal.png' => 'journal.png',
+'General Ledger--Reports.png' => 'gl_report.png',
+'Master Data--Add Assembly.png' => 'assembly_add.png',
+'Master Data--Add Customer.png' => 'customer_add.png',
+'Master Data--Add License.png' => 'license_add.png',
+'Master Data--Add Part.png' => 'part_add.png',
+'Master Data--Add Project.png' => 'project_add.png',
+'Master Data--Add Service.png' => 'service_add.png',
+'Master Data--Add Vendor.png' => 'vendor_add.png',
+'Master Data.png' => 'master_data.png',
+'Master Data--Reports--Assemblies.png' => 'assembly_report.png',
+'Master Data--Reports--Customers.png' => 'customer_report.png',
+'Master Data--Reports--Licenses.png' => 'license_report.png',
+'Master Data--Reports--Parts.png' => 'part_report.png',
+'Master Data--Reports.png' => 'master_data_report.png',
+'Master Data--Reports--Projects.png' => 'project_report.png',
+'Master Data--Reports--Projecttransactions.png' => 'project_transaction_report.png',
+'Master Data--Reports--Services.png' => 'service_report.png',
+'Master Data--Reports--Vendors.png' => 'vendor_report.png',
+'Master Data--Update Prices.png' => 'prices_update.png',
+'Neues Fenster.png' => 'window_new.png',
+'phone.png' => 'phone.png',
+'Program--Logout.png' => 'logout.png',
+'Program.png' => 'program.png',
+'Program--Preferences.png' => 'preferences.png',
+'Program--Version.png' => 'version.png',
+'Reports--Balance Sheet.png' => 'balance_sheet.png',
+'Reports--Chart of Accounts.png' => 'chart_of_accounts.png',
+'Reports--Income Statement.png' => 'income_statement.png',
+'Reports.png' => 'report.png',
+'Reports--UStVa.png' => 'ustva.png',
+'System.png' => 'system.png',
+'Warehouse.png' => 'warehouse.png',
+'Warehouse--Produce Assembly.png' => 'assembly_produce.png',
+'MDI-Text-Editor-16x16.png' => 'mdi_text_editor.png',
+'Productivity' => 'productivity.png',
+);
+
+my %symlinks = (
+'mdi_text_editor.png' => 'delivery_order_add.png', # symlink to MDI-Txt_editor
+'mdi_text_editor.png' => 'delivery_order_report.png', # symlink to MDI-Txt_editor
+);
+
+sub checks {
+ # check 1: no duplicate targets
+ my %seen;
+ for (values %icons) {
+ next unless defined $_;
+ die "duplicate target: $_" if $seen{$_}++;
+ }
+
+ # check2: all targets should end in .png, otherwise there's a typo
+ for (values %icons) {
+ next unless defined $_;
+ die "target does not end in .png: $_" unless /\.png$/;
+ }
+
+ # check 3: all sources need to be real files in this dir
+ for (keys %icons) {
+ next unless defined $_;
+ die "key $_ is not a file!" unless -f $_;
+ }
+
+ # check 4: all keys in symlinks need to be a target in icons
+ for (keys %symlinks) {
+ no warnings 'uninitialized';
+ die "can't symlink this, because it's not a target of renaming: $_" unless { reverse %icons }->{$_};
+ }
+}
+
+sub make_icons {
+ # now do the actual renaming
+ while (my ($from, $to) = each(%icons)) {
+ if (defined $to) {
+ # rename
+ system("git mv '$from' '$to'");
+ } else {
+ # delete
+ system("git rm '$from'");
+ }
+ }
+
+ # and do some symlinking
+ while (my ($from, $to) = each(%symlinks)) {
+ system("ln -s '$from' '$to'");
+ system("git add '$to'");
+ }
+}
+
+sub translate_menu {
+ my ($menu_file) = @_;
+
+ my $new_file = $menu_file;
+ $new_file =~ s/\./_new\./;
+
+ open my $in, "<", $menu_file or die "error opening $menu_file: $!";
+ open my $out, ">", $new_file or die "error opening $new_file: $!";
+
+ while (<$in>) {
+ print $out $_;
+ if (/^\[(.*)\]$/) {
+ my $name = $1;
+ # look if we got this in %icons
+ if ($icons{ $name . '.png' }) {
+ my $new_name = $icons{ $name . '.png' };
+ $new_name =~ s/\.png$//;
+ print $out "ICON=$new_name\n";
+ } else {
+ warn "don't know what '$name' is in $menu_file";
+ }
+ }
+ }
+ system("mv $new_file $menu_file");
+}
+
+# checks();
+# make_icons();
+
+translate_menu('menus/erp.ini');
+translate_menu('menus/admin.ini');
+translate_menu('menus/crm.ini');
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use SL::Dispatcher;
+use SL::Inifile;
+use SL::LXDebug;
+use Data::Dumper;
+use JSON;
+use YAML;
+use Cwd;
+
+$::lxdebug = LXDebug->new;
+
+my %menu_files = (
+ 'menus/erp.ini' => 'menus/user/00-erp.yaml',
+ 'menus/crm.ini' => 'menus/user/10-crm.yaml',
+ 'menus/admin.ini' => 'menus/admin/00-admin.yaml',
+);
+
+my %known_arguments = (
+ ICON => 'icon',
+ ACCESS => 'access',
+ INSTANCE_CONF => 'INSTANCE_CONF',
+ module => 'module',
+ submenu => 'submenu',
+ target => 'target',
+ href => 'href',
+);
+
+sub translate_to_yaml {
+ my ($menu_file, $new_file) = @_;
+
+ my %counter;
+
+ my $menu = Inifile->new($menu_file);
+ my @menu_items = map { +{ %{ $menu->{$_} }, ID => $_ } } @{ delete $menu->{ORDER} };
+
+ for my $item (@menu_items) {
+ # parse id
+ my @tokens = split /--/, delete $item->{ID};
+ my $name = pop @tokens;
+ my $parent = join '_', map { lc $_ } @tokens;
+ my $id = join '_', grep $_, $parent, lc $name;
+
+ # move unknown arguments to param subhash
+ my @keys = keys %$item;
+ my %params;
+ for (@keys) {
+ next if $known_arguments{$_};
+ $params{$_} = delete $item->{$_};
+ }
+
+ $item->{params} = \%params if keys %params;
+
+ # sanitize keys
+ for (keys %known_arguments) {
+ next unless exists $item->{$_};
+ my $val = delete $item->{$_};
+ $item->{ $known_arguments{$_} } = $val;
+ }
+
+ # sanitize submenu
+ if ($item->{submenu}) {
+ delete $item->{submenu};
+ }
+
+ #sanitize those stupid menu inlinks
+ if ($item->{module} eq 'menu.pl') {
+ delete $item->{module};
+ delete $item->{action};
+ delete $item->{target};
+ }
+
+ # sanitize INSTANCE_CONF
+ if ($item->{INSTANCE_CONF}) {
+ my $instance_conf = delete $item->{INSTANCE_CONF};
+ if ($item->{access}) {
+ if ($item->{access} =~ /\W/) {
+ $item->{access} = "client/$instance_conf & ( $item->{access} )";
+ } else {
+ $item->{access} = "client/$instance_conf & $item->{access}";
+ }
+ } else {
+ $item->{access} = "client/$instance_conf";
+ }
+ }
+
+ # make controller.pl implicit
+ if ($item->{module} && $item->{module} eq 'controller.pl') {
+ delete $item->{module};
+ }
+
+ # add id
+ $item->{id} = $id;
+ $item->{id} =~ s/[^\w]+/_/g;
+
+ # add to name
+ $item->{name} = $name;
+
+ # add parent
+ if ($parent) {
+ $item->{parent} = $parent;
+ $item->{parent} =~ s/[^\w]+/_/g if $item->{parent};
+ }
+
+ # add order
+ $item->{order} = 100 * ++$counter{ $item->{parent} };
+ }
+
+ if ($menu_file =~ /crm/) {
+ $menu_items[0]{order} = 50; # crm first
+ }
+
+ open my $out_file, '>:utf8', $new_file or die $!;
+ print $out_file yaml_dump(\@menu_items);
+}
+
+sub yaml_dump {
+ my ($ary_ref) = @_;
+ # YAML dumps keys lexically sorted, which isn't what we want.
+ # we want this order:
+ my @order = qw(
+ parent
+ id
+ name
+ icon
+ order
+ access
+ href
+ module
+ target
+ params
+ );
+
+ # ...oh and we want action in params first
+ #
+ # why this? because:
+ # 1. parent is what is used to anchor. one could argue that id should be
+ # first, but parent is easier for understanding structure.
+ # 2. after parent the logical structure is
+ # 1. id
+ # 2. stuff related to vidual presentation (name/icon)
+ # 3. stuff needed for logical presentaion (order/access)
+ # 4. stuff related to the action after clicking it
+ # 3. without parent and href (the second is pretty rare) the keys are nicely
+ # ascending in length, which is very easy to parse visually.
+
+ my $yaml = "---\n";
+ for my $node (@$ary_ref) {
+ my $first = 0;
+ for my $key (@order) {
+ next unless exists $node->{$key};
+ $yaml .= ($first++ ? ' ' : '- ') . $key . ":";
+ if (!ref $node->{$key}) {
+ $yaml .= ' ' . $node->{$key} . "\n";
+ } else {
+ $yaml .= "\n";
+ for ('action', grep !/^action$/, keys %{ $node->{$key} }) {
+ next unless exists $node->{$key}{$_};
+ $yaml .= " $_: $node->{$key}{$_}\n";
+ }
+ }
+
+ }
+ }
+
+ $yaml;
+}
+
+while (my ($in, $out) = each(%menu_files)) {
+ translate_to_yaml($in, $out);
+}
+
--- /dev/null
+-- @tag: add_master_rights
+-- @description: Rechte in die Datenbank migrieren
+-- @depends: release_3_2_0
+-- @charset: utf-8
+-- @locales: Master Data
+-- @locales: Create customers and vendors. Edit all vendors. Edit only customers where salesman equals employee (login)
+-- @locales: Create customers and vendors. Edit all vendors. Edit all customers
+-- @locales: Create and edit parts, services, assemblies
+-- @locales: Show details and reports of parts, services, assemblies
+-- @locales: Create and edit projects
+-- @locales: AR
+-- @locales: Create and edit requirement specs
+-- @locales: Create and edit sales quotations
+-- @locales: Create and edit sales orders
+-- @locales: Create and edit sales delivery orders
+-- @locales: Create and edit invoices and credit notes
+-- @locales: Create and edit dunnings
+-- @locales: Edit sales letters
+-- @locales: View/edit all employees sales documents
+-- @locales: Edit prices and discount (if not used, textfield is ONLY set readonly)
+-- @locales: Show AR transactions as part of AR invoice report
+-- @locales: Show delivery plan
+-- @locales: Show delivery value report
+-- @locales: Show sales letters report
+-- @locales: AP
+-- @locales: Create and edit RFQs
+-- @locales: Create and edit purchase orders
+-- @locales: Create and edit purchase delivery orders
+-- @locales: Create and edit vendor invoices
+-- @locales: Show AP transactions as part of AP invoice report
+-- @locales: Warehouse management
+-- @locales: View warehouse content
+-- @locales: Warehouse management
+-- @locales: General ledger and cash
+-- @locales: Transactions, AR transactions, AP transactions
+-- @locales: DATEV Export
+-- @locales: Receipt, payment, reconciliation
+-- @locales: Bank transactions
+-- @locales: Reports
+-- @locales: All reports
+-- @locales: Advance turnover tax return
+-- @locales: Batch Printing
+-- @locales: Batch Printing
+-- @locales: Configuration
+-- @locales: Change kivitendo installation settings (most entries in the 'System' menu)
+-- @locales: Client administration: configuration, editing templates, task server control, background jobs (remaining entries in the 'System' menu)
+-- @locales: Others
+-- @locales: May set the BCC field when sending emails
+-- @locales: Productivity
+-- @locales: Show administration link
+
+CREATE TABLE auth.master_rights (
+ id SERIAL PRIMARY KEY,
+ position INTEGER NOT NULL,
+ name TEXT NOT NULL UNIQUE,
+ description TEXT NOT NULL,
+ category BOOLEAN NOT NULL DEFAULT FALSE
+);
+
+
+INSERT INTO auth.master_rights (position, name, description, category) VALUES ( 1, 'master_data', 'Master Data', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES ( 2, 'customer_vendor_edit', 'Create customers and vendors. Edit all vendors. Edit only customers where salesman equals employee (login)');
+INSERT INTO auth.master_rights (position, name, description) VALUES ( 3, 'customer_vendor_all_edit', 'Create customers and vendors. Edit all vendors. Edit all customers');
+INSERT INTO auth.master_rights (position, name, description) VALUES ( 4, 'part_service_assembly_edit', 'Create and edit parts, services, assemblies');
+INSERT INTO auth.master_rights (position, name, description) VALUES ( 5, 'part_service_assembly_details', 'Show details and reports of parts, services, assemblies');
+INSERT INTO auth.master_rights (position, name, description) VALUES ( 6, 'project_edit', 'Create and edit projects');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES ( 7, 'ar', 'AR', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES ( 8, 'requirement_spec_edit', 'Create and edit requirement specs');
+INSERT INTO auth.master_rights (position, name, description) VALUES ( 9, 'sales_quotation_edit', 'Create and edit sales quotations');
+INSERT INTO auth.master_rights (position, name, description) VALUES (10, 'sales_order_edit', 'Create and edit sales orders');
+INSERT INTO auth.master_rights (position, name, description) VALUES (11, 'sales_delivery_order_edit', 'Create and edit sales delivery orders');
+INSERT INTO auth.master_rights (position, name, description) VALUES (12, 'invoice_edit', 'Create and edit invoices and credit notes');
+INSERT INTO auth.master_rights (position, name, description) VALUES (13, 'dunning_edit', 'Create and edit dunnings');
+INSERT INTO auth.master_rights (position, name, description) VALUES (14, 'sales_letter_edit', 'Edit sales letters');
+INSERT INTO auth.master_rights (position, name, description) VALUES (15, 'sales_all_edit', 'View/edit all employees sales documents');
+INSERT INTO auth.master_rights (position, name, description) VALUES (16, 'edit_prices', 'Edit prices and discount (if not used, textfield is ONLY set readonly)');
+INSERT INTO auth.master_rights (position, name, description) VALUES (17, 'show_ar_transactions', 'Show AR transactions as part of AR invoice report');
+INSERT INTO auth.master_rights (position, name, description) VALUES (18, 'delivery_plan', 'Show delivery plan');
+INSERT INTO auth.master_rights (position, name, description) VALUES (19, 'delivery_value_report', 'Show delivery value report');
+INSERT INTO auth.master_rights (position, name, description) VALUES (20, 'sales_letter_report', 'Show sales letters report');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES (21, 'ap', 'AP', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES (22, 'request_quotation_edit', 'Create and edit RFQs');
+INSERT INTO auth.master_rights (position, name, description) VALUES (23, 'purchase_order_edit', 'Create and edit purchase orders');
+INSERT INTO auth.master_rights (position, name, description) VALUES (24, 'purchase_delivery_order_edit', 'Create and edit purchase delivery orders');
+INSERT INTO auth.master_rights (position, name, description) VALUES (25, 'vendor_invoice_edit', 'Create and edit vendor invoices');
+INSERT INTO auth.master_rights (position, name, description) VALUES (26, 'show_ap_transactions', 'Show AP transactions as part of AP invoice report');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES (27, 'warehouse', 'Warehouse management', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES (28, 'warehouse_contents', 'View warehouse content');
+INSERT INTO auth.master_rights (position, name, description) VALUES (29, 'warehouse_management', 'Warehouse management');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES (30, 'general_ledger_cash', 'General ledger and cash', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES (31, 'general_ledger', 'Transactions, AR transactions, AP transactions');
+INSERT INTO auth.master_rights (position, name, description) VALUES (32, 'datev_export', 'DATEV Export');
+INSERT INTO auth.master_rights (position, name, description) VALUES (33, 'cash', 'Receipt, payment, reconciliation');
+INSERT INTO auth.master_rights (position, name, description) VALUES (34, 'bank_transaction', 'Bank transactions');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES (35, 'reports', 'Reports', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES (36, 'report', 'All reports');
+INSERT INTO auth.master_rights (position, name, description) VALUES (37, 'advance_turnover_tax_return', 'Advance turnover tax return');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES (38, 'batch_printing_category', 'Batch Printing', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES (39, 'batch_printing', 'Batch Printing');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES (40, 'configuration', 'Configuration', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES (41, 'config', 'Change kivitendo installation settings (most entries in the ''System'' menu)');
+INSERT INTO auth.master_rights (position, name, description) VALUES (42, 'admin', 'Client administration: configuration, editing templates, task server control, background jobs (remaining entries in the ''System'' menu)');
+INSERT INTO auth.master_rights (position, name, description, category) VALUES (43, 'others', 'Others', TRUE);
+INSERT INTO auth.master_rights (position, name, description) VALUES (44, 'email_bcc', 'May set the BCC field when sending emails');
+INSERT INTO auth.master_rights (position, name, description) VALUES (45, 'productivity', 'Productivity');
+INSERT INTO auth.master_rights (position, name, description) VALUES (46, 'display_admin_link', 'Show administration link');
use Data::Dumper;
use Support::TestSetup;
+use SL::Locale;
sub new_item {
return AttrDurationTestDummy->new(@_);
Support::TestSetup::login();
my $item;
+$::locale = Locale->new('en');
+
### attr_duration
# Wenn das Attribut undef ist:
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%]
-<script type="text/javascript" src="js/wz_tooltip.js"></script>
-
<h1>[% title %]</h1>
[%- INCLUDE 'common/flash.html' %]
var node = document.getElementsByName(prop_id)[0];
node.parentNode.removeChild(node);
}
- UnTip();
var invoices = document.getElementById('assigned_invoices_' + bt_id);
$.ajax({
//-->
</script>
-
<td><a href=# onclick="create_invoice('[% bt.id %]'); return false;">[% 'Create invoice' | $T8 %]</a></td>
<td id="assigned_invoices_[% bt.id %]" nowrap></td>
[% IF debug %]
- <td onmouseover="Tip('[% FOREACH match = bt.rule_matches %] [% match %]<br> [% END %]')" onmouseout="UnTip()">[% bt.agreement %]</td>
+ <td class="tooltipster-html" title="[% FOREACH match = bt.rule_matches %] [% match %]<br> [% END %]">[% bt.agreement %]</td>
[% END %]
<td>
[% FOREACH prop = bt.proposals %]
- <div name='[% prop.id %]'> <a href=# onclick="add_invoices('[% bt.id %]', '[% prop.id %]', '[% HTML.escape(prop.invnumber) %]');"
- onmouseover="Tip('<table><tr><th></th><th>[% 'Suggested invoice' | $T8 %][% IF !prop.is_sales %] ([% 'AP' | $T8 %])[% END %]</th><th>[% 'Bank transaction' | $T8 %]</th></tr><tr><th>[% 'Amount' | $T8 %]</th><td>[% LxERP.format_amount(prop.amount, 2) %] ([% 'open' | $T8 %]: [% LxERP.format_amount(prop.open_amount, 2) %])</td><td>[% LxERP.format_amount(bt.amount, 2) %]</td></tr>[% IF prop.skonto_date %]<tr><th>[% 'Payment terms' | $T8 %]</th><td>[% LxERP.format_amount(prop.amount_less_skonto, 2) %] [% 'until' | $T8 %] [% HTML.escape(prop.skonto_date.to_kivitendo) %] ([% prop.percent_skonto * 100 %] %)</td><td></td></tr>[% END %]<tr><th>[% 'Customer/Vendor' | $T8 %]</th><td>[% HTML.escape(prop.customer.displayable_name) %][% HTML.escape(prop.vendor.displayable_name) %]</td><td>[% HTML.escape(bt.remote_name) %]</td></tr><tr><th>[% 'Invoice Date' | $T8 %]</th><td>[% HTML.escape(prop.transdate_as_date) %]</td><td>[% HTML.escape(bt.transdate_as_date) %] ([% HTML.escape(bt.transdate.utc_rd_days - prop.transdate.utc_rd_days) %])</td></tr><tr><th>[% 'Invoice Number' | $T8 %]</th><td>[% HTML.escape(prop.invnumber) %]</td><td>[% HTML.escape(bt.purpose) %]</td></tr></table>')" onmouseout="UnTip()"
- class=[% IF bt.agreement >= 5 %]"green"[% ELSIF bt.agreement < 5 and bt.agreement >= 3 %]"orange"[% ELSE %]"red"[% END %]>←[% HTML.escape(prop.invnumber)%]</a></div>
+ <div name='[% prop.id %]'>
+ <a href=# onclick="add_invoices('[% bt.id %]', '[% prop.id %]', '[% HTML.escape(prop.invnumber) %]');"
+ title="<table><tr><th></th><th>[% 'Suggested invoice' | $T8 %][% IF !prop.is_sales %] ([% 'AP' | $T8 %])[% END %]</th><th>[% 'Bank transaction' | $T8 %]</th></tr><tr><th>[% 'Amount' | $T8 %]</th><td>[% LxERP.format_amount(prop.amount, 2) %] ([% 'open' | $T8 %]: [% LxERP.format_amount(prop.open_amount, 2) %])</td><td>[% LxERP.format_amount(bt.amount, 2) %]</td></tr>[% IF prop.skonto_date %]<tr><th>[% 'Payment terms' | $T8 %]</th><td>[% LxERP.format_amount(prop.amount_less_skonto, 2) %] [% 'until' | $T8 %] [% HTML.escape(prop.skonto_date.to_kivitendo) %] ([% prop.percent_skonto * 100 %] %)</td><td></td></tr>[% END %]<tr><th>[% 'Customer/Vendor' | $T8 %]</th><td>[% HTML.escape(prop.customer.displayable_name) %][% HTML.escape(prop.vendor.displayable_name) %]</td><td>[% HTML.escape(bt.remote_name) %]</td></tr><tr><th>[% 'Invoice Date' | $T8 %]</th><td>[% HTML.escape(prop.transdate_as_date) %]</td><td>[% HTML.escape(bt.transdate_as_date) %] ([% HTML.escape(bt.transdate.utc_rd_days - prop.transdate.utc_rd_days) %])</td></tr><tr><th>[% 'Invoice Number' | $T8 %]</th><td>[% HTML.escape(prop.invnumber) %]</td><td>[% HTML.escape(bt.purpose) %]</td></tr></table>"
+ class="[% IF bt.agreement >= 5 %]green[% ELSIF bt.agreement < 5 and bt.agreement >= 3 %]orange[% ELSE %]red[% END %] tooltipster-html">←[% HTML.escape(prop.invnumber)%]</a></div>
[% END %]
</td>
<td align=right>[% bt.transdate_as_date %]</td>
[%- END %]
</form>
-
-<script type="text/javascript" src="js/wz_tooltip.js"></script>
[% L.textarea_tag("notes", P.restricted_html(notes), class="texteditor", style="width: 600px; height: 200px") %]
</td>
<td>
- <textarea name="formel" rows="[% HTML.escape(notes_rows) %]" cols="30" wrap="soft" onmouseover="Tip('[% 'The formula needs the following syntax:<br>For regular article:<br>Variablename= Variable Unit;<br>Variablename2= Variable2 Unit2;<br>...<br>###<br>Variable + ( Variable2 / Variable )<br><b>Please be beware of the spaces in the formula</b><br>' | $T8 %]', STICKY, true)" onmouseout="UnTip()">[% HTML.escape(formel) %]</textarea>
+ <textarea name="formel" rows="[% HTML.escape(notes_rows) %]" cols="30" wrap="soft" class="tooltipster-html" title="[% 'The formula needs the following syntax:<br>For regular article:<br>Variablename= Variable Unit;<br>Variablename2= Variable2 Unit2;<br>...<br>###<br>Variable + ( Variable2 / Variable )<br><b>Please be beware of the spaces in the formula</b><br>' | $T8 %]">[% HTML.escape(formel) %]</textarea>
</td>
</tr>
</table>
[%- USE T8 %]
-[% USE HTML %][%- USE LxERP -%]
+[%- USE L %]
+[%- USE HTML %]
+[%- USE LxERP -%]
<div id="main_menu_div"></div>
-
[%- SET main_id = '100' %]
<ul id="main_menu_model" style='display:none'>
- [%- FOREACH mainitem = menu_items %]
+ [%- FOREACH node = menu.tree %]
+ [%- NEXT UNLESS node.visible %]
[%- SET main_id = main_id + 1 %]
- <li id="[% main_id %]"[% IF mainitem.image %] itemIcon="[% mainitem.image %]"[% END %]>
- <a href="[% IF mainitem.href %][% mainitem.href %][% ELSE %]#[% END %]"[% IF mainitem.target && (mainitem.target != 'main_window') %] target="[% HTML.escape(mainitem.target) %]"[% END %]>
- [%- HTML.escape(mainitem.title) %]
- </a>
- [%- IF mainitem.subitems %]
- <ul[%- IF force_ul_width %] width="[% mainitem.max_width * 10 %]"[% END %]>
+ <li id="[% main_id %]"[% IF icon_path(node.icon) %] itemIcon="[% icon_path(node.icon) %]"[% END %]>
+ [% L.link(menu.href_for_node(node) || '#', menu.name_for_node(node), target=node.target) %]
+ [%- IF node.children %]
+ <ul width="[% max_width(node) %]">
[%- SET sub1_id = main_id * 100 %]
- [%- FOREACH sub1item = mainitem.subitems %]
+ [%- FOREACH sub1node = node.children %]
+ [%- NEXT UNLESS sub1node.visible %]
[%- SET sub1_id = sub1_id + 1 %]
- <li id="[% sub1_id %]"[% IF sub1item.image %] itemIcon="[% sub1item.image %]"[% END %]>
- <a href="[% IF sub1item.href %][% sub1item.href %][% ELSE %]#[% END %]"[% IF sub1item.target && (sub1item.target != 'main_window') %] target="[% HTML.escape(sub1item.target) %]"[% END %]>
- [%- HTML.escape(sub1item.title) %]
- </a>
- [%- IF sub1item.subitems %]
- <ul[%- IF force_ul_width %] width="[% sub1item.max_width * 10 %]"[% END %]>
+ <li id="[% sub1_id %]"[% IF icon_path(sub1node.icon) %] itemIcon="[% icon_path(sub1node.icon) %]"[% END %]>
+ [% L.link(menu.href_for_node(sub1node) || '#', menu.name_for_node(sub1node), target=sub1node.target) %]
+ [%- IF sub1node.children %]
+ <ul width="[% max_width(sub1node) %]">
[%- SET sub2_id = sub1_id * 100 %]
- [%- FOREACH sub2item = sub1item.subitems %]
+ [%- FOREACH sub2node = sub1node.children %]
+ [%- NEXT UNLESS sub2node.visible %]
[%- SET sub2_id = sub2_id + 1 %]
- <li id="[% sub2_id %]"[% IF sub2item.image %] itemIcon="[% sub2item.image %]"[% END %]>
- <a href="[% IF sub2item.href %][% sub2item.href %][% ELSE %]#[% END %]"[% IF sub2item.target && (sub2item.target != 'main_window') %] target="[% HTML.escape(sub2item.target) %]"[% END %]>
- [%- HTML.escape(sub2item.title) %]
- </a>
+ <li id="[% sub2_id %]"[% IF icon_path(sub2node.icon) %] itemIcon="[% icon_path(sub2node.icon) %]"[% END %]>
+ [% L.link(menu.href_for_node(sub2node) || '#', menu.name_for_node(sub2node), target=sub2node.target) %]
</li>
[%- END %]
</ul>
</li>
[%- END %]
</ul>
-
- <script type="text/javascript">
- <!--
-
-$(function(){
- DHTMLSuite.createStandardObjects();
-
- DHTMLSuite.configObj.setImagePath('image/dhtmlsuite/');
-
- var menu_model = new DHTMLSuite.menuModel();
- menu_model.addItemsFromMarkup('main_menu_model');
- menu_model.init();
-
- var menu_bar = new DHTMLSuite.menuBar();
- menu_bar.addMenuItems(menu_model);
- menu_bar.setTarget('main_menu_div');
- menu_bar.init();
-});
-
-
-
-function open_url(url, target) {
-
-}
-
- -->
- </script>
- <div id="menuv3">[% menu %]</div>
- <div style="clear: both;"></div>
+[%- USE L %]
+[%- USE HTML %]
+<div id="menuv3">[% FOREACH node = menu.tree %][% NEXT UNLESS node.visible %]<ul><li>[% PROCESS submenu top=1 %]</li></ul>[% END %]</div>
+<div style="clear: both;"></div>
+[%- %]
+[%- BLOCK submenu %]
+ [%- IF top %]<h2>[% menu.name_for_node(node) | html %]</h2>
+ [%- ELSIF node.children %]<div class="x">[% menu.name_for_node(node) | html %]</div>
+ [%- ELSE %][% L.link(menu.href_for_node(node), menu.name_for_node(node), title=menu.name_for_node(node), target=node.target) %]
+ [%- END %]
+ [%- IF node.children %]<ul>[%- FOREACH node = node.children %][% NEXT UNLESS node.visible %]<li>[% PROCESS submenu top=0 %]</li>[% END %]</ul>[%- END %]
+[%- END %]