Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision b251cc22

Von Sven Schöling vor mehr als 9 Jahren hinzugefügt

  • ID b251cc22f355941217493073e124ba3878d5530f
  • Vorgänger 15b1558e
  • Nachfolger cd306e61

Menüstruktur auf YAML geändert

Unterschiede anzeigen:

SL/Layout/Admin.pm
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')),
]
}
SL/Layout/Base.pm
}
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 {
SL/Layout/CssMenu.pm
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 .= "&amp;" . $::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;
SL/Layout/Javascript.pm
$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($menu_item->{ICON});
$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.png";
return unless -f $img;
return $img;
}
1;
SL/Layout/MenuLeft.pm
sub section_menu {
my ($menu) = @_;
my @menuorder = @{ $menu->{ORDER} };
my @items;
my @id_stack = (-1);
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 } $menuitem->{ICON};
my $level = (0 + $item =~ s/--/--/g);
my $spacer = "s" . $level;
for my $node ($menu->tree_walk) {
my $level = $node->{level};
# do id stack
push @id_stack, -1 if $level > $#id_stack;
pop @id_stack while $level < $#id_stack;
$id_stack[-1]++;
my $label = $::locale->text($olabel);
my $label = $::locale->text($node->{name});
my $href = $menu->href_for_node($node);
$menuitem->{module} ||= $::form->{script};
$menuitem->{action} ||= "section_menu";
$menuitem->{href} ||= "$menuitem->{module}?action=$menuitem->{action}";
my @common_args = ($label, "s" . $level, join '_', @id_stack);
# add other params
foreach my $key (keys %$menuitem) {
next if $key =~ /target|module|action|href|ICON/;
$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, join '_', @id_stack);
if ($spacer eq 's0') { # toplevel
push @items, [ @common_args, "icon24 $icon_class", 'm' ];
} 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' ];
} elsif ($menuitem->{module}) {
push @items, [ @common_args, "icon16 $icon_class", 'i', $menuitem->{href}, $menuitem->{target} ];
} else {
push @items, [ @common_args, "icon16 $node->{icon}", 'i', $href, $node->{target} ];
}
}
SL/Menu.pm
#=====================================================================
# 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;
our @ISA = qw(Inifile);
use YAML::XS ();
use File::Spec;
use SL::MoreCommon qw(uri_encode);
sub new {
$main::lxdebug->enter_sub();
my ($package, $domain) = @_;
my ($package, @menufiles) = @_;
my $path = File::Spec->catdir('menus', $domain);
my $self = $package->SUPER::new($menufiles[0]);
opendir my $dir, $path or die "can't open $path: $!";
my @files = sort grep -f "$path/$_", readdir $dir;
close $dir;
for (@menufiles[1..$#menufiles]) {
my $inifile = Inifile->new($_);
push @{ $self->{ORDER} }, @{ delete $inifile->{ORDER} };
$self->{$_} = $inifile->{$_} for keys %$inifile;
my $nodes = [];
my $nodes_by_id = {};
for my $file (@files) {
my $data = YAML::XS::LoadFile(File::Spec->catfile($path, $file));
_merge($nodes, $nodes_by_id, $data);
}
$self->set_access;
$main::lxdebug->leave_sub();
my $self = bless {
nodes => $nodes,
by_id => $nodes_by_id,
}, $package;
$self->build_tree;
$self->set_access;
return $self;
}
sub menuitem_new {
$main::lxdebug->enter_sub(LXDebug::DEBUG2());
sub _merge {
my ($nodes, $by_id, $data) = @_;
my ($self, $name, $item) = @_;
die 'not an array ref' unless $data && 'ARRAY' eq ref $data; # TODO check this sooner, to get better diag to user
my $module = $self->{$name}->{module} || $::form->{script};
my $action = $self->{$name}->{action};
for my $node (@$data) {
my $id = $node->{id};
$item->{target} = $self->{$name}->{target} || "main_window";
$item->{href} = $self->{$name}->{href} || "${module}?action=" . $::form->escape($action);
my $merge_to = $by_id->{$id};
my @vars = qw(module target href);
push @vars, 'action' unless ($self->{$name}->{href});
if (!$merge_to) {
push @$nodes, $node;
$by_id->{$id} = $node;
next;
}
map { delete $self->{$name}{$_} } @vars;
# 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};
}
}
}
}
# 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);
sub build_tree {
my ($self) = @_;
# 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-existant parent $node->{parent}";
}
$main::lxdebug->leave_sub(LXDebug::DEBUG2());
}
my %by_parent;
# order them by parent
for my $node ($self->nodes) {
push @{ $by_parent{ $node->{parent} } //= [] }, $node;
}
sub access_control {
$main::lxdebug->enter_sub(2);
my $tree = { };
$self->{by_id}{''} = $tree;
my ($self, $myconfig, $menulevel) = @_;
my @menu = ();
for (keys %by_parent) {
my $parent = $self->{by_id}{$_};
$parent->{children} = [ sort { $a->{order} <=> $b->{order} } @{ $by_parent{$_} } ];
}
_set_level_rec($tree->{children}, 0);
$self->{tree} = $tree->{children};
}
sub _set_level_rec {
my ($ary_ref, $level) = @_;
if (!$menulevel) {
@menu = grep { !/--/ } @{ $self->{ORDER} };
} else {
@menu = grep { /^${menulevel}--/ } @{ $self->{ORDER} };
for (@$ary_ref) {
$_->{level} = $level;
_set_level_rec($_->{children}, $level + 1) if $_->{children};
}
}
$main::lxdebug->leave_sub(2);
sub nodes {
@{ $_[0]{nodes} }
}
sub tree_walk {
my ($self, $all) = @_;
return @menu;
_tree_walk_rec($self->{tree}, $all);
}
sub parse_access_string {
my $self = shift;
my $key = shift;
my $access = shift;
sub _tree_walk_rec {
my ($ary_ref, $all) = @_;
map { $_->{children} ? ($_, _tree_walk_rec($_->{children}, $all)) : ($_) } grep { $all || $_->{visible} } @$ary_ref;
}
my $form = $main::form;
my $auth = $main::auth;
my $myconfig = \%main::myconfig;
sub parse_access_string {
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 in menu.ini for 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 in menu.ini for 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 in menu.ini for 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 set_access {
my $self = shift;
my $key;
foreach $key (@{ $self->{ORDER} }) {
my $entry = $self->{$key};
$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;
if ($key =~ m/--/) {
my $parent = $key;
substr($parent, rindex($parent, '--')) = '';
$entry->{GRANTED} &&= $self->{$parent}->{GRANTED};
}
$entry->{VISIBLE} = $entry->{GRANTED};
}
foreach $key (reverse @{ $self->{ORDER} }) {
my $entry = $self->{$key};
sub href_for_node {
my ($self, $node) = @_;
if ($entry->{IS_MENU}) {
$entry->{VISIBLE} &&= $entry->{NUM_VISIBLE_CHILDREN} > 0;
}
return undef if !$node->{href} && !$node->{module} && !$node->{params};
next if (($key !~ m/--/) || !$entry->{VISIBLE});
my $href = $node->{href} || $node->{module} || 'controller.pl';
my @tokens;
my $parent = $key;
substr($parent, rindex($parent, '--')) = '';
$self->{$parent}->{NUM_VISIBLE_CHILDREN}++;
while (my ($key, $value) = each %{ $node->{params} }) {
push @tokens, uri_encode($key, 1) . "=" . uri_encode($value, 1);
}
# $self->dump_visible();
return join '?', $href, grep $_, join '&', @tokens;
}
$self->{ORDER} = [ grep { $self->{$_}->{VISIBLE} } @{ $self->{ORDER} } ];
sub name_for_node {
$::locale->text($_[1]{name})
}
{ 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 parse_instance_conf_string {
my ($self, $setting) = @_;
return $::instance_conf->data->{$setting};
}
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;
}
}
}
menus/admin/00-admin.yaml
---
- 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
menus/user/00-erp.yaml
---
- 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
module: menu.pl
params:
action: acc_menu
- 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
module: menu.pl
params:
action: acc_menu
- 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
module: menu.pl
params:
action: acc_menu
- 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
module: menu.pl
params:
action: acc_menu
- 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
module: menu.pl
params:
action: acc_menu
- 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
module: menu.pl
params:
action: acc_menu
- 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
module: menu.pl
params:
action: acc_menu
- 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
... Dieser Diff wurde abgeschnitten, weil er die maximale Anzahl anzuzeigender Zeilen überschreitet.

Auch abrufbar als: Unified diff