Revision b251cc22
Von Sven Schöling vor mehr als 9 Jahren hinzugefügt
SL/Layout/Admin.pm | ||
---|---|---|
11 | 11 |
sub init_sub_layouts { |
12 | 12 |
[ |
13 | 13 |
SL::Layout::None->new, |
14 |
SL::Layout::CssMenu->new(menu => Menu->new('menus/admin.ini')),
|
|
14 |
SL::Layout::CssMenu->new(menu => SL::Menu->new('admin')),
|
|
15 | 15 |
] |
16 | 16 |
} |
17 | 17 |
|
SL/Layout/Base.pm | ||
---|---|---|
29 | 29 |
} |
30 | 30 |
|
31 | 31 |
sub init_menu { |
32 |
my @menu_files = qw(menus/erp.ini); |
|
33 |
unshift @menu_files, 'menus/crm.ini' if $::instance_conf->crm_installed; |
|
34 |
Menu->new(@menu_files); |
|
32 |
SL::Menu->new('user'); |
|
35 | 33 |
} |
36 | 34 |
|
37 | 35 |
sub init_auto_reload_resources_param { |
SL/Layout/CssMenu.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
use parent qw(SL::Layout::Base); |
5 | 5 |
|
6 |
use URI; |
|
7 |
|
|
8 |
sub print_menu { |
|
9 |
my ($self, $parent, $depth) = @_; |
|
10 |
|
|
11 |
my $html; |
|
12 |
|
|
13 |
die if ($depth * 1 > 5); |
|
14 |
|
|
15 |
my @menuorder; |
|
16 |
my $menu = $self->menu; |
|
17 |
|
|
18 |
@menuorder = $menu->access_control(\%::myconfig, $parent); |
|
19 |
|
|
20 |
$parent .= "--" if ($parent); |
|
21 |
|
|
22 |
foreach my $item (@menuorder) { |
|
23 |
substr($item, 0, length($parent)) = ""; |
|
24 |
next if (($item eq "") || ($item =~ /--/)); |
|
25 |
|
|
26 |
my $menu_item = $menu->{"${parent}${item}"}; |
|
27 |
my $menu_title = $::locale->text($item); |
|
28 |
my $menu_text = $menu_title; |
|
29 |
|
|
30 |
if ($menu_item->{"submenu"} || !defined($menu_item->{"module"}) && !defined($menu_item->{href})) { |
|
31 |
|
|
32 |
my $h = $self->print_menu("${parent}${item}", $depth * 1 + 1)."\n"; |
|
33 |
if (!$parent) { |
|
34 |
$html .= qq|<ul><li><h2>${menu_text}</h2><ul>${h}</ul></li></ul>\n|; |
|
35 |
} else { |
|
36 |
$html .= qq|<li><div class="x">${menu_text}</div><ul>${h}</ul></li>\n|; |
|
37 |
} |
|
38 |
} else { |
|
39 |
if ($self->{sub_class} && $depth > 1) { |
|
40 |
$html .= qq|<li class='sub'>|; |
|
41 |
} else { |
|
42 |
$html .= qq|<li>|; |
|
43 |
} |
|
44 |
$html .= $self->menuitem_v3("${parent}$item", { "title" => $menu_title }); |
|
45 |
$html .= qq|${menu_text}</a></li>\n|; |
|
46 |
} |
|
47 |
} |
|
48 |
|
|
49 |
return $html; |
|
50 |
} |
|
51 |
|
|
52 |
sub menuitem_v3 { |
|
53 |
$main::lxdebug->enter_sub(); |
|
54 |
|
|
55 |
my ($self, $item, $other) = @_; |
|
56 |
my $menuitem = $self->menu->{$item}; |
|
57 |
|
|
58 |
my $action = "section_menu"; |
|
59 |
my $module; |
|
60 |
|
|
61 |
if ($menuitem->{module}) { |
|
62 |
$module = $menuitem->{module}; |
|
63 |
} |
|
64 |
if ($menuitem->{action}) { |
|
65 |
$action = $menuitem->{action}; |
|
66 |
} |
|
67 |
|
|
68 |
my $level = $::form->escape($item); |
|
69 |
|
|
70 |
my @vars; |
|
71 |
my $target = $menuitem->{target} ? qq| target="| . $::form->escape($menuitem->{target}) . '"' : ''; |
|
72 |
my $str = qq|<a${target} href="|; |
|
73 |
|
|
74 |
if ($menuitem->{href}) { |
|
75 |
$main::lxdebug->leave_sub(); |
|
76 |
return $str . $menuitem->{href} . '">'; |
|
77 |
} |
|
78 |
|
|
79 |
$str .= qq|$module?action=| . $::form->escape($action); |
|
80 |
|
|
81 |
map { delete $menuitem->{$_} } qw(module action target href); |
|
82 |
|
|
83 |
# add other params |
|
84 |
foreach my $key (keys %{ $menuitem }) { |
|
85 |
$str .= "&" . $::form->escape($key, 1) . "="; |
|
86 |
my ($value, $conf) = split(/=/, $menuitem->{$key}, 2); |
|
87 |
$value = $::myconfig{$value} . "/$conf" if ($conf); |
|
88 |
$str .= $::form->escape($value, 1); |
|
89 |
} |
|
90 |
|
|
91 |
$str .= '"'; |
|
92 |
|
|
93 |
if ($other) { |
|
94 |
foreach my $key (keys(%{$other})) { |
|
95 |
$str .= qq| ${key}="| . $::form->quote($other->{$key}) . qq|"|; |
|
96 |
} |
|
97 |
} |
|
98 |
|
|
99 |
$str .= ">"; |
|
100 |
|
|
101 |
$main::lxdebug->leave_sub(); |
|
102 |
|
|
103 |
return $str; |
|
104 |
} |
|
105 |
|
|
106 | 6 |
sub use_stylesheet { |
107 | 7 |
qw(icons16.css frame_header/header.css), |
108 | 8 |
} |
109 | 9 |
|
110 | 10 |
sub pre_content { |
111 |
$_[0]->presenter->render('menu/menuv3', |
|
112 |
menu => $_[0]->print_menu, |
|
113 |
); |
|
11 |
$_[0]->presenter->render('menu/menuv3', menu => $_[0]->menu); |
|
114 | 12 |
} |
115 | 13 |
|
116 | 14 |
1; |
SL/Layout/Javascript.pm | ||
---|---|---|
21 | 21 |
$self->SUPER::use_javascript(@_); |
22 | 22 |
} |
23 | 23 |
|
24 |
sub javascripts_inline { |
|
25 |
$_[0]->SUPER::javascripts_inline, |
|
26 |
<<'EOJS' |
|
27 |
DHTMLSuite.createStandardObjects(); |
|
28 |
DHTMLSuite.configObj.setImagePath('image/dhtmlsuite/'); |
|
29 |
var menu_model = new DHTMLSuite.menuModel(); |
|
30 |
menu_model.addItemsFromMarkup('main_menu_model'); |
|
31 |
menu_model.init(); |
|
32 |
var menu_bar = new DHTMLSuite.menuBar(); |
|
33 |
menu_bar.addMenuItems(menu_model); |
|
34 |
menu_bar.setTarget('main_menu_div'); |
|
35 |
menu_bar.init(); |
|
36 |
EOJS |
|
37 |
} |
|
38 |
|
|
24 | 39 |
sub pre_content { |
25 | 40 |
$_[0]->SUPER::pre_content . |
26 |
&display |
|
41 |
$_[0]->presenter->render("menu/menunew", |
|
42 |
force_ul_width => 1, |
|
43 |
menu => $_[0]->menu, |
|
44 |
icon_path => sub { my $img = "image/icons/16x16/$_[0].png"; -f $img ? $img : () }, |
|
45 |
max_width => sub { 10 * max map { length $::locale->text($_->{name}) } @{ $_[0]{children} || [] } }, |
|
46 |
); |
|
27 | 47 |
} |
28 | 48 |
|
29 | 49 |
sub start_content { |
... | ... | |
45 | 65 |
$_[0]->SUPER::stylesheets; |
46 | 66 |
} |
47 | 67 |
|
48 |
sub display { |
|
49 |
my ($self) = @_; |
|
50 |
|
|
51 |
$self->presenter->render("menu/menunew", |
|
52 |
force_ul_width => 1, |
|
53 |
menu_items => $self->acc_menu, |
|
54 |
); |
|
55 |
} |
|
56 |
|
|
57 |
sub acc_menu { |
|
58 |
my ($self) = @_; |
|
59 |
|
|
60 |
my $menu = $self->menu; |
|
61 |
|
|
62 |
my $all_items = []; |
|
63 |
$self->create_menu($menu, $all_items); |
|
64 |
|
|
65 |
my $item = { 'subitems' => $all_items }; |
|
66 |
calculate_width($item); |
|
67 |
|
|
68 |
return $all_items; |
|
69 |
} |
|
70 |
|
|
71 |
sub calculate_width { |
|
72 |
my $item = shift; |
|
73 |
|
|
74 |
$item->{max_width} = max map { length $_->{title} } @{ $item->{subitems} }; |
|
75 |
|
|
76 |
foreach my $subitem (@{ $item->{subitems} }) { |
|
77 |
calculate_width($subitem) if ($subitem->{subitems}); |
|
78 |
} |
|
79 |
} |
|
80 |
|
|
81 |
sub create_menu { |
|
82 |
my ($self, $menu, $all_items, $parent, $depth) = @_; |
|
83 |
my $html; |
|
84 |
|
|
85 |
my $form = $main::form; |
|
86 |
my %myconfig = %main::myconfig; |
|
87 |
|
|
88 |
$depth ||= 0; |
|
89 |
|
|
90 |
die if ($depth * 1 > 5); |
|
91 |
|
|
92 |
my @menuorder = $menu->access_control(\%myconfig, $parent); |
|
93 |
$parent .= "--" if ($parent); |
|
94 |
$parent ||= ''; |
|
95 |
|
|
96 |
foreach my $name (@menuorder) { |
|
97 |
substr($name, 0, length($parent), ""); |
|
98 |
next if (($name eq "") || ($name =~ /--/)); |
|
99 |
|
|
100 |
my $menu_item = $menu->{"${parent}${name}"}; |
|
101 |
my $item = { 'title' => $::locale->text($name) }; |
|
102 |
push @{ $all_items }, $item; |
|
103 |
|
|
104 |
if ($menu_item->{submenu} || (!defined($menu_item->{module}) && !defined($menu_item->{href}))) { |
|
105 |
$item->{subitems} = []; |
|
106 |
$item->{image} = _icon_path($menu_item->{ICON}); |
|
107 |
$self->create_menu($menu, $item->{subitems}, "${parent}${name}", $depth * 1 + 1); |
|
108 |
|
|
109 |
} else { |
|
110 |
$item->{image} = _icon_path("${parent}${name}.png"); |
|
111 |
$menu->menuitem_new("${parent}${name}", $item); |
|
112 |
} |
|
113 |
} |
|
114 |
} |
|
115 |
|
|
116 |
sub _icon_path { |
|
117 |
my ($label, $size) = @_; |
|
118 |
|
|
119 |
$size ||= 16; |
|
120 |
|
|
121 |
my $img = "image/icons/${size}x${size}/$label.png"; |
|
122 |
|
|
123 |
return unless -f $img; |
|
124 |
return $img; |
|
125 |
} |
|
126 |
|
|
127 | 68 |
1; |
SL/Layout/MenuLeft.pm | ||
---|---|---|
40 | 40 |
|
41 | 41 |
sub section_menu { |
42 | 42 |
my ($menu) = @_; |
43 |
my @menuorder = @{ $menu->{ORDER} }; |
|
44 | 43 |
my @items; |
45 | 44 |
my @id_stack = (-1); |
46 | 45 |
|
47 |
for my $item (@menuorder) { |
|
48 |
my $menuitem = $menu->{$item}; |
|
49 |
my $olabel = apply { s/.*--// } $item; |
|
50 |
my $ml = apply { s/--.*// } $item; |
|
51 |
my $icon_class = apply { $_ = lc $_; s/[^a-z0-9_-]/-/g } $menuitem->{ICON}; |
|
52 |
my $level = (0 + $item =~ s/--/--/g); |
|
53 |
my $spacer = "s" . $level; |
|
46 |
for my $node ($menu->tree_walk) { |
|
47 |
my $level = $node->{level}; |
|
54 | 48 |
|
55 | 49 |
# do id stack |
56 | 50 |
push @id_stack, -1 if $level > $#id_stack; |
57 | 51 |
pop @id_stack while $level < $#id_stack; |
58 | 52 |
$id_stack[-1]++; |
59 | 53 |
|
60 |
my $label = $::locale->text($olabel); |
|
54 |
my $label = $::locale->text($node->{name}); |
|
55 |
my $href = $menu->href_for_node($node); |
|
61 | 56 |
|
62 |
$menuitem->{module} ||= $::form->{script}; |
|
63 |
$menuitem->{action} ||= "section_menu"; |
|
64 |
$menuitem->{href} ||= "$menuitem->{module}?action=$menuitem->{action}"; |
|
57 |
my @common_args = ($label, "s" . $level, join '_', @id_stack); |
|
65 | 58 |
|
66 |
# add other params |
|
67 |
foreach my $key (keys %$menuitem) { |
|
68 |
next if $key =~ /target|module|action|href|ICON/; |
|
69 |
$menuitem->{href} .= "&" . $::form->escape($key, 1) . "="; |
|
70 |
my ($value, $conf) = split(/=/, $menuitem->{$key}, 2); |
|
71 |
$value = $::myconfig{$value} . "/$conf" if ($conf); |
|
72 |
$menuitem->{href} .= $::form->escape($value, 1); |
|
73 |
} |
|
74 |
|
|
75 |
my @common_args = ($label, $spacer, join '_', @id_stack); |
|
76 |
|
|
77 |
if ($spacer eq 's0') { # toplevel |
|
78 |
push @items, [ @common_args, "icon24 $icon_class", 'm' ]; |
|
79 |
} elsif ($menuitem->{submenu}) { |
|
59 |
if (!$node->{parent}) { # toplevel |
|
60 |
push @items, [ @common_args, "icon24 $node->{icon}", 'm' ]; |
|
61 |
} elsif ($node->{children}) { |
|
80 | 62 |
push @items, [ @common_args, "icon16 submenu", 'sm' ]; |
81 |
} elsif ($menuitem->{module}) {
|
|
82 |
push @items, [ @common_args, "icon16 $icon_class", 'i', $menuitem->{href}, $menuitem->{target} ];
|
|
63 |
} else {
|
|
64 |
push @items, [ @common_args, "icon16 $node->{icon}", 'i', $href, $node->{target} ];
|
|
83 | 65 |
} |
84 | 66 |
} |
85 | 67 |
|
SL/Menu.pm | ||
---|---|---|
1 |
#===================================================================== |
|
2 |
# LX-Office ERP |
|
3 |
# Copyright (C) 2004 |
|
4 |
# Based on SQL-Ledger Version 2.1.9 |
|
5 |
# Web http://www.lx-office.org |
|
6 |
# |
|
7 |
#===================================================================== |
|
8 |
# SQL-Ledger Accounting |
|
9 |
# Copyright (C) 2001 |
|
10 |
# |
|
11 |
# Author: Dieter Simader |
|
12 |
# Email: dsimader@sql-ledger.org |
|
13 |
# Web: http://www.sql-ledger.org |
|
14 |
# |
|
15 |
# Contributors: |
|
16 |
# |
|
17 |
# This program is free software; you can redistribute it and/or modify |
|
18 |
# it under the terms of the GNU General Public License as published by |
|
19 |
# the Free Software Foundation; either version 2 of the License, or |
|
20 |
# (at your option) any later version. |
|
21 |
# |
|
22 |
# This program is distributed in the hope that it will be useful, |
|
23 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
24 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
25 |
# GNU General Public License for more details. |
|
26 |
# You should have received a copy of the GNU General Public License |
|
27 |
# along with this program; if not, write to the Free Software |
|
28 |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
29 |
#===================================================================== |
|
30 |
# |
|
31 |
# routines for menu items |
|
32 |
# |
|
33 |
#===================================================================== |
|
34 |
|
|
35 |
package Menu; |
|
1 |
package SL::Menu; |
|
36 | 2 |
|
37 | 3 |
use strict; |
38 | 4 |
|
39 | 5 |
use SL::Auth; |
40 |
use SL::Inifile; |
|
41 |
|
|
42 |
our @ISA = qw(Inifile); |
|
43 |
|
|
6 |
use YAML::XS (); |
|
7 |
use File::Spec; |
|
8 |
use SL::MoreCommon qw(uri_encode); |
|
44 | 9 |
|
45 | 10 |
sub new { |
46 |
$main::lxdebug->enter_sub();
|
|
11 |
my ($package, $domain) = @_;
|
|
47 | 12 |
|
48 |
my ($package, @menufiles) = @_;
|
|
13 |
my $path = File::Spec->catdir('menus', $domain);
|
|
49 | 14 |
|
50 |
my $self = $package->SUPER::new($menufiles[0]); |
|
15 |
opendir my $dir, $path or die "can't open $path: $!"; |
|
16 |
my @files = sort grep -f "$path/$_", readdir $dir; |
|
17 |
close $dir; |
|
51 | 18 |
|
52 |
for (@menufiles[1..$#menufiles]) { |
|
53 |
my $inifile = Inifile->new($_); |
|
54 |
push @{ $self->{ORDER} }, @{ delete $inifile->{ORDER} }; |
|
55 |
$self->{$_} = $inifile->{$_} for keys %$inifile; |
|
19 |
my $nodes = []; |
|
20 |
my $nodes_by_id = {}; |
|
21 |
for my $file (@files) { |
|
22 |
my $data = YAML::XS::LoadFile(File::Spec->catfile($path, $file)); |
|
23 |
_merge($nodes, $nodes_by_id, $data); |
|
56 | 24 |
} |
57 | 25 |
|
58 |
$self->set_access; |
|
59 | 26 |
|
60 |
$main::lxdebug->leave_sub(); |
|
27 |
my $self = bless { |
|
28 |
nodes => $nodes, |
|
29 |
by_id => $nodes_by_id, |
|
30 |
}, $package; |
|
31 |
|
|
32 |
$self->build_tree; |
|
33 |
$self->set_access; |
|
61 | 34 |
|
62 | 35 |
return $self; |
63 | 36 |
} |
64 | 37 |
|
65 |
sub menuitem_new {
|
|
66 |
$main::lxdebug->enter_sub(LXDebug::DEBUG2());
|
|
38 |
sub _merge {
|
|
39 |
my ($nodes, $by_id, $data) = @_;
|
|
67 | 40 |
|
68 |
my ($self, $name, $item) = @_;
|
|
41 |
die 'not an array ref' unless $data && 'ARRAY' eq ref $data; # TODO check this sooner, to get better diag to user
|
|
69 | 42 |
|
70 |
my $module = $self->{$name}->{module} || $::form->{script};
|
|
71 |
my $action = $self->{$name}->{action};
|
|
43 |
for my $node (@$data) {
|
|
44 |
my $id = $node->{id};
|
|
72 | 45 |
|
73 |
$item->{target} = $self->{$name}->{target} || "main_window"; |
|
74 |
$item->{href} = $self->{$name}->{href} || "${module}?action=" . $::form->escape($action); |
|
46 |
my $merge_to = $by_id->{$id}; |
|
75 | 47 |
|
76 |
my @vars = qw(module target href); |
|
77 |
push @vars, 'action' unless ($self->{$name}->{href}); |
|
48 |
if (!$merge_to) { |
|
49 |
push @$nodes, $node; |
|
50 |
$by_id->{$id} = $node; |
|
51 |
next; |
|
52 |
} |
|
78 | 53 |
|
79 |
map { delete $self->{$name}{$_} } @vars; |
|
54 |
# TODO make this a real recursive merge |
|
55 |
# TODO add support for arrays |
|
56 |
|
|
57 |
# merge keys except params |
|
58 |
for my $key (keys %$node) { |
|
59 |
if (ref $node->{$key}) { |
|
60 |
if ('HASH' eq ref $node->{$key}) { |
|
61 |
$merge_to->{$key} = {} if !exists $merge_to->{$key} || 'HASH' ne ref $merge_to->{$key}; |
|
62 |
for (keys %{ $node->{params} }) { |
|
63 |
$merge_to->{$key}{$_} = $node->{params}{$_}; |
|
64 |
} |
|
65 |
} else { |
|
66 |
die "unsupported structure @{[ ref $node->{$key} ]}"; |
|
67 |
} |
|
68 |
} else { |
|
69 |
$merge_to->{$key} = $node->{$key}; |
|
70 |
} |
|
71 |
} |
|
72 |
} |
|
73 |
} |
|
80 | 74 |
|
81 |
# add other params |
|
82 |
foreach my $key (keys %{ $self->{$name} }) { |
|
83 |
my ($value, $conf) = split(m/=/, $self->{$name}->{$key}, 2); |
|
84 |
$value = $::myconfig->{$value} . "/$conf" if ($conf); |
|
85 |
$item->{href} .= "&" . $::form->escape($key) . "=" . $::form->escape($value); |
|
75 |
sub build_tree { |
|
76 |
my ($self) = @_; |
|
77 |
|
|
78 |
# first, some sanity check. are all parents valid ids or empty? |
|
79 |
for my $node ($self->nodes) { |
|
80 |
next if !exists $node->{parent} || !$node->{parent} || $self->{by_id}->{$node->{id}}; |
|
81 |
die "menu: node $node->{id} has non-existant parent $node->{parent}"; |
|
86 | 82 |
} |
87 | 83 |
|
88 |
$main::lxdebug->leave_sub(LXDebug::DEBUG2()); |
|
89 |
} |
|
84 |
my %by_parent; |
|
85 |
# order them by parent |
|
86 |
for my $node ($self->nodes) { |
|
87 |
push @{ $by_parent{ $node->{parent} } //= [] }, $node; |
|
88 |
} |
|
90 | 89 |
|
91 |
sub access_control {
|
|
92 |
$main::lxdebug->enter_sub(2);
|
|
90 |
my $tree = { };
|
|
91 |
$self->{by_id}{''} = $tree;
|
|
93 | 92 |
|
94 |
my ($self, $myconfig, $menulevel) = @_; |
|
95 | 93 |
|
96 |
my @menu = (); |
|
94 |
for (keys %by_parent) { |
|
95 |
my $parent = $self->{by_id}{$_}; |
|
96 |
$parent->{children} = [ sort { $a->{order} <=> $b->{order} } @{ $by_parent{$_} } ]; |
|
97 |
} |
|
98 |
|
|
99 |
_set_level_rec($tree->{children}, 0); |
|
100 |
|
|
101 |
$self->{tree} = $tree->{children}; |
|
102 |
} |
|
103 |
|
|
104 |
sub _set_level_rec { |
|
105 |
my ($ary_ref, $level) = @_; |
|
97 | 106 |
|
98 |
if (!$menulevel) { |
|
99 |
@menu = grep { !/--/ } @{ $self->{ORDER} }; |
|
100 |
} else { |
|
101 |
@menu = grep { /^${menulevel}--/ } @{ $self->{ORDER} }; |
|
107 |
for (@$ary_ref) { |
|
108 |
$_->{level} = $level; |
|
109 |
_set_level_rec($_->{children}, $level + 1) if $_->{children}; |
|
102 | 110 |
} |
111 |
} |
|
103 | 112 |
|
104 |
$main::lxdebug->leave_sub(2); |
|
113 |
sub nodes { |
|
114 |
@{ $_[0]{nodes} } |
|
115 |
} |
|
116 |
|
|
117 |
sub tree_walk { |
|
118 |
my ($self, $all) = @_; |
|
105 | 119 |
|
106 |
return @menu;
|
|
120 |
_tree_walk_rec($self->{tree}, $all);
|
|
107 | 121 |
} |
108 | 122 |
|
109 |
sub parse_access_string {
|
|
110 |
my $self = shift;
|
|
111 |
my $key = shift;
|
|
112 |
my $access = shift;
|
|
123 |
sub _tree_walk_rec {
|
|
124 |
my ($ary_ref, $all) = @_;
|
|
125 |
map { $_->{children} ? ($_, _tree_walk_rec($_->{children}, $all)) : ($_) } grep { $all || $_->{visible} } @$ary_ref;
|
|
126 |
}
|
|
113 | 127 |
|
114 |
my $form = $main::form; |
|
115 |
my $auth = $main::auth; |
|
116 |
my $myconfig = \%main::myconfig; |
|
128 |
sub parse_access_string { |
|
129 |
my ($self, $node) = @_; |
|
117 | 130 |
|
118 | 131 |
my @stack; |
119 | 132 |
my $cur_ary = []; |
120 | 133 |
|
121 | 134 |
push @stack, $cur_ary; |
122 | 135 |
|
123 |
while ($access =~ m/^([a-z_]+|\||\&|\(|\)|\s+)/) { |
|
136 |
my $access = $node->{access}; |
|
137 |
|
|
138 |
while ($access =~ m/^([a-z_\/]+|\||\&|\(|\)|\s+)/) { |
|
124 | 139 |
my $token = $1; |
125 | 140 |
substr($access, 0, length($1)) = ""; |
126 | 141 |
|
... | ... | |
135 | 150 |
} elsif ($token eq ")") { |
136 | 151 |
pop @stack; |
137 | 152 |
if (!@stack) { |
138 |
$form->error("Error in menu.ini for entry ${key}: missing '('");
|
|
153 |
die "Error in menu.ini for entry $node->{id}: missing '('";
|
|
139 | 154 |
} |
140 | 155 |
$cur_ary = $stack[-1]; |
141 | 156 |
|
... | ... | |
143 | 158 |
push @{$cur_ary}, $token; |
144 | 159 |
|
145 | 160 |
} else { |
146 |
push @{$cur_ary}, $auth->check_right($::myconfig{login}, $token, 1); |
|
161 |
if ($token =~ m{^ client / (.*) }x) { |
|
162 |
push @{$cur_ary}, $self->parse_instance_conf_string($1); |
|
163 |
} else { |
|
164 |
push @{$cur_ary}, $::auth->check_right($::myconfig{login}, $token, 1); |
|
165 |
} |
|
147 | 166 |
} |
148 | 167 |
} |
149 | 168 |
|
150 | 169 |
if ($access) { |
151 |
$form->error("Error in menu.ini for entry ${key}: unrecognized token at the start of '$access'\n");
|
|
170 |
die "Error in menu.ini for entry $node->{id}: unrecognized token at the start of '$access'\n";
|
|
152 | 171 |
} |
153 | 172 |
|
154 | 173 |
if (1 < scalar @stack) { |
155 |
$main::form->error("Error in menu.ini for entry ${key}: Missing ')'\n");
|
|
174 |
die "Error in menu.ini for entry $node->{id}: Missing ')'\n";
|
|
156 | 175 |
} |
157 | 176 |
|
158 | 177 |
return SL::Auth::evaluate_rights_ary($stack[0]); |
159 | 178 |
} |
160 | 179 |
|
161 |
sub parse_instance_conf_string { |
|
162 |
my ($self, $setting) = @_; |
|
163 |
return $::instance_conf->data->{$setting}; |
|
164 |
} |
|
165 |
|
|
166 |
sub set_access { |
|
167 |
my $self = shift; |
|
168 |
|
|
169 |
my $key; |
|
170 |
|
|
171 |
foreach $key (@{ $self->{ORDER} }) { |
|
172 |
my $entry = $self->{$key}; |
|
173 |
|
|
174 |
$entry->{GRANTED} = $entry->{ACCESS} ? $self->parse_access_string($key, $entry->{ACCESS}) : 1; |
|
175 |
$entry->{GRANTED} &&= $self->parse_instance_conf_string($entry->{INSTANCE_CONF}) if $entry->{INSTANCE_CONF}; |
|
176 |
$entry->{IS_MENU} = $entry->{submenu} || ($key !~ m/--/); |
|
177 |
$entry->{NUM_VISIBLE_CHILDREN} = 0; |
|
178 |
|
|
179 |
if ($key =~ m/--/) { |
|
180 |
my $parent = $key; |
|
181 |
substr($parent, rindex($parent, '--')) = ''; |
|
182 |
$entry->{GRANTED} &&= $self->{$parent}->{GRANTED}; |
|
183 |
} |
|
184 |
|
|
185 |
$entry->{VISIBLE} = $entry->{GRANTED}; |
|
186 |
} |
|
187 |
|
|
188 |
foreach $key (reverse @{ $self->{ORDER} }) { |
|
189 |
my $entry = $self->{$key}; |
|
180 |
sub href_for_node { |
|
181 |
my ($self, $node) = @_; |
|
190 | 182 |
|
191 |
if ($entry->{IS_MENU}) { |
|
192 |
$entry->{VISIBLE} &&= $entry->{NUM_VISIBLE_CHILDREN} > 0; |
|
193 |
} |
|
183 |
return undef if !$node->{href} && !$node->{module} && !$node->{params}; |
|
194 | 184 |
|
195 |
next if (($key !~ m/--/) || !$entry->{VISIBLE}); |
|
185 |
my $href = $node->{href} || $node->{module} || 'controller.pl'; |
|
186 |
my @tokens; |
|
196 | 187 |
|
197 |
my $parent = $key; |
|
198 |
substr($parent, rindex($parent, '--')) = ''; |
|
199 |
$self->{$parent}->{NUM_VISIBLE_CHILDREN}++; |
|
188 |
while (my ($key, $value) = each %{ $node->{params} }) { |
|
189 |
push @tokens, uri_encode($key, 1) . "=" . uri_encode($value, 1); |
|
200 | 190 |
} |
201 | 191 |
|
202 |
# $self->dump_visible(); |
|
192 |
return join '?', $href, grep $_, join '&', @tokens; |
|
193 |
} |
|
203 | 194 |
|
204 |
$self->{ORDER} = [ grep { $self->{$_}->{VISIBLE} } @{ $self->{ORDER} } ]; |
|
195 |
sub name_for_node { |
|
196 |
$::locale->text($_[1]{name}) |
|
197 |
} |
|
205 | 198 |
|
206 |
{ no strict 'refs'; |
|
207 |
# ToDO: fix this. nuke and pave algorithm without type checking screams for problems. |
|
208 |
map { delete @{$self->{$_}}{qw(GRANTED IS_MENU NUM_VISIBLE_CHILDREN VISIBLE ACCESS)} if ($_ ne 'ORDER') } keys %{ $self }; |
|
209 |
} |
|
199 |
sub parse_instance_conf_string { |
|
200 |
my ($self, $setting) = @_; |
|
201 |
return $::instance_conf->data->{$setting}; |
|
210 | 202 |
} |
211 | 203 |
|
212 |
sub dump_visible { |
|
213 |
my $self = shift; |
|
214 |
foreach my $key (@{ $self->{ORDER} }) { |
|
215 |
my $entry = $self->{$key}; |
|
216 |
$main::lxdebug->message(0, "$entry->{GRANTED} $entry->{VISIBLE} $entry->{NUM_VISIBLE_CHILDREN} $key"); |
|
204 |
sub set_access { |
|
205 |
my ($self) = @_; |
|
206 |
# 1. evaluate access for all |
|
207 |
# 2. if a menu has no visible children, its not visible either |
|
208 |
|
|
209 |
for my $node (reverse $self->tree_walk("all")) { |
|
210 |
$node->{visible} = $node->{access} ? $self->parse_access_string($node) |
|
211 |
: !$node->{children} ? 1 |
|
212 |
: $node->{visible_children} ? 1 |
|
213 |
: 0; |
|
214 |
if ($node->{visible} && $node->{parent}) { |
|
215 |
$self->{by_id}{ $node->{parent} }{visible_children} = 1; |
|
216 |
} |
|
217 | 217 |
} |
218 | 218 |
} |
219 | 219 |
|
menus/admin/00-admin.yaml | ||
---|---|---|
1 |
--- |
|
2 |
- id: users_clients_and_user_groups |
|
3 |
name: Users, Clients and User Groups |
|
4 |
order: 100 |
|
5 |
- parent: users_clients_and_user_groups |
|
6 |
id: users_clients_and_user_groups_list_users_clients_and_user_groups |
|
7 |
name: List Users, Clients and User Groups |
|
8 |
order: 100 |
|
9 |
params: |
|
10 |
action: Admin/show |
|
11 |
- parent: users_clients_and_user_groups |
|
12 |
id: users_clients_and_user_groups_add_user |
|
13 |
name: Add User |
|
14 |
order: 200 |
|
15 |
params: |
|
16 |
action: Admin/new_user |
|
17 |
- parent: users_clients_and_user_groups |
|
18 |
id: users_clients_and_user_groups_add_client |
|
19 |
name: Add Client |
|
20 |
order: 300 |
|
21 |
params: |
|
22 |
action: Admin/new_client |
|
23 |
- parent: users_clients_and_user_groups |
|
24 |
id: users_clients_and_user_groups_add_user_group |
|
25 |
name: Add User Group |
|
26 |
order: 400 |
|
27 |
params: |
|
28 |
action: Admin/new_group |
|
29 |
- id: database_management |
|
30 |
name: Database Management |
|
31 |
order: 200 |
|
32 |
- parent: database_management |
|
33 |
id: database_management_create_dataset |
|
34 |
name: Create Dataset |
|
35 |
order: 100 |
|
36 |
params: |
|
37 |
action: Admin/create_dataset_login |
|
38 |
- parent: database_management |
|
39 |
id: database_management_delete_dataset |
|
40 |
name: Delete Dataset |
|
41 |
order: 200 |
|
42 |
params: |
|
43 |
action: Admin/delete_dataset_login |
|
44 |
- id: printer_management |
|
45 |
name: Printer Management |
|
46 |
order: 300 |
|
47 |
- parent: printer_management |
|
48 |
id: printer_management_list_printers |
|
49 |
name: List Printers |
|
50 |
order: 100 |
|
51 |
params: |
|
52 |
action: Admin/list_printers |
|
53 |
- parent: printer_management |
|
54 |
id: printer_management_add_printer |
|
55 |
name: Add Printer |
|
56 |
order: 200 |
|
57 |
params: |
|
58 |
action: Admin/new_printer |
|
59 |
- id: system |
|
60 |
name: System |
|
61 |
icon: system |
|
62 |
order: 400 |
|
63 |
- parent: system |
|
64 |
id: system_lock_and_unlock_installation |
|
65 |
name: Lock and unlock installation |
|
66 |
order: 100 |
|
67 |
params: |
|
68 |
action: Admin/show_lock |
|
69 |
- parent: system |
|
70 |
id: system_documentation_in_german_ |
|
71 |
name: Documentation (in German) |
|
72 |
order: 200 |
|
73 |
href: doc/kivitendo-Dokumentation.pdf |
|
74 |
target: _blank |
|
75 |
- parent: system |
|
76 |
id: system_kivitendo_website_external_ |
|
77 |
name: kivitendo website (external) |
|
78 |
order: 300 |
|
79 |
href: http://www.kivitendo.de/ |
|
80 |
target: _blank |
|
81 |
- parent: system |
|
82 |
id: system_to_user_login |
|
83 |
name: To user login |
|
84 |
order: 400 |
|
85 |
params: |
|
86 |
action: LoginScreen/user_login |
|
87 |
- parent: system |
|
88 |
id: system_logout |
|
89 |
name: Logout |
|
90 |
order: 500 |
|
91 |
params: |
|
92 |
action: Admin/logout |
menus/user/00-erp.yaml | ||
---|---|---|
1 |
--- |
|
2 |
- id: master_data |
|
3 |
name: Master Data |
|
4 |
icon: master_data |
|
5 |
order: 100 |
|
6 |
- parent: master_data |
|
7 |
id: master_data_add_customer |
|
8 |
name: Add Customer |
|
9 |
icon: customer_add |
|
10 |
order: 100 |
|
11 |
access: customer_vendor_edit |
|
12 |
params: |
|
13 |
action: CustomerVendor/add |
|
14 |
db: customer |
|
15 |
- parent: master_data |
|
16 |
id: master_data_add_vendor |
|
17 |
name: Add Vendor |
|
18 |
icon: vendor_add |
|
19 |
order: 200 |
|
20 |
access: customer_vendor_edit |
|
21 |
params: |
|
22 |
action: CustomerVendor/add |
|
23 |
db: vendor |
|
24 |
- parent: master_data |
|
25 |
id: master_data_add_part |
|
26 |
name: Add Part |
|
27 |
icon: part_add |
|
28 |
order: 300 |
|
29 |
access: part_service_assembly_edit |
|
30 |
module: ic.pl |
|
31 |
params: |
|
32 |
action: add |
|
33 |
item: part |
|
34 |
- parent: master_data |
|
35 |
id: master_data_add_service |
|
36 |
name: Add Service |
|
37 |
icon: service_add |
|
38 |
order: 400 |
|
39 |
access: part_service_assembly_edit |
|
40 |
module: ic.pl |
|
41 |
params: |
|
42 |
action: add |
|
43 |
item: service |
|
44 |
- parent: master_data |
|
45 |
id: master_data_add_assembly |
|
46 |
name: Add Assembly |
|
47 |
icon: assembly_add |
|
48 |
order: 500 |
|
49 |
access: part_service_assembly_edit |
|
50 |
module: ic.pl |
|
51 |
params: |
|
52 |
action: add |
|
53 |
item: assembly |
|
54 |
- parent: master_data |
|
55 |
id: master_data_add_project |
|
56 |
name: Add Project |
|
57 |
icon: project_add |
|
58 |
order: 600 |
|
59 |
access: project_edit |
|
60 |
params: |
|
61 |
action: Project/new |
|
62 |
- parent: master_data |
|
63 |
id: master_data_add_requirement_spec_template |
|
64 |
name: Add Requirement Spec Template |
|
65 |
order: 700 |
|
66 |
access: requirement_spec_edit |
|
67 |
params: |
|
68 |
action: RequirementSpec/new |
|
69 |
is_template: 1 |
|
70 |
- parent: master_data |
|
71 |
id: master_data_update_prices |
|
72 |
name: Update Prices |
|
73 |
icon: prices_update |
|
74 |
order: 800 |
|
75 |
access: part_service_assembly_edit |
|
76 |
module: ic.pl |
|
77 |
params: |
|
78 |
action: search_update_prices |
|
79 |
- parent: master_data |
|
80 |
id: master_data_price_rules |
|
81 |
name: Price Rules |
|
82 |
order: 900 |
|
83 |
access: part_service_assembly_edit |
|
84 |
params: |
|
85 |
action: PriceRule/list |
|
86 |
filter.obsolete: 0 |
|
87 |
- parent: master_data |
|
88 |
id: master_data_reports |
|
89 |
name: Reports |
|
90 |
icon: master_data_report |
|
91 |
order: 1000 |
|
92 |
module: menu.pl |
|
93 |
params: |
|
94 |
action: acc_menu |
|
95 |
- parent: master_data_reports |
|
96 |
id: master_data_reports_customers |
|
97 |
name: Customers |
|
98 |
icon: customer_report |
|
99 |
order: 100 |
|
100 |
access: customer_vendor_edit |
|
101 |
params: |
|
102 |
action: CustomerVendor/search |
|
103 |
db: customer |
|
104 |
- parent: master_data_reports |
|
105 |
id: master_data_reports_vendors |
|
106 |
name: Vendors |
|
107 |
icon: vendor_report |
|
108 |
order: 200 |
|
109 |
access: customer_vendor_edit |
|
110 |
params: |
|
111 |
action: CustomerVendor/search |
|
112 |
db: vendor |
|
113 |
- parent: master_data_reports |
|
114 |
id: master_data_reports_contacts |
|
115 |
name: Contacts |
|
116 |
order: 300 |
|
117 |
access: customer_vendor_edit |
|
118 |
params: |
|
119 |
action: CustomerVendor/search_contact |
|
120 |
db: customer |
|
121 |
- parent: master_data_reports |
|
122 |
id: master_data_reports_parts |
|
123 |
name: Parts |
|
124 |
icon: part_report |
|
125 |
order: 400 |
|
126 |
access: part_service_assembly_details |
|
127 |
module: ic.pl |
|
128 |
params: |
|
129 |
action: search |
|
130 |
searchitems: part |
|
131 |
- parent: master_data_reports |
|
132 |
id: master_data_reports_services |
|
133 |
name: Services |
|
134 |
icon: service_report |
|
135 |
order: 500 |
|
136 |
access: part_service_assembly_details |
|
137 |
module: ic.pl |
|
138 |
params: |
|
139 |
action: search |
|
140 |
searchitems: service |
|
141 |
- parent: master_data_reports |
|
142 |
id: master_data_reports_assemblies |
|
143 |
name: Assemblies |
|
144 |
icon: assembly_report |
|
145 |
order: 600 |
|
146 |
access: part_service_assembly_details |
|
147 |
module: ic.pl |
|
148 |
params: |
|
149 |
action: search |
|
150 |
searchitems: assembly |
|
151 |
- parent: master_data_reports |
|
152 |
id: master_data_reports_projects |
|
153 |
name: Projects |
|
154 |
icon: project_report |
|
155 |
order: 700 |
|
156 |
access: project_edit |
|
157 |
params: |
|
158 |
action: Project/list |
|
159 |
filter.active: active |
|
160 |
filter.valid: valid |
|
161 |
- parent: master_data_reports |
|
162 |
id: master_data_reports_requirement_spec_templates |
|
163 |
name: Requirement Spec Templates |
|
164 |
order: 800 |
|
165 |
access: requirement_spec_edit |
|
166 |
params: |
|
167 |
action: RequirementSpec/list |
|
168 |
is_template: 1 |
|
169 |
- id: ar |
|
170 |
name: AR |
|
171 |
icon: ar |
|
172 |
order: 200 |
|
173 |
- parent: ar |
|
174 |
id: ar_add_requirement_spec |
|
175 |
name: Add Requirement Spec |
|
176 |
order: 100 |
|
177 |
access: requirement_spec_edit |
|
178 |
params: |
|
179 |
action: RequirementSpec/new |
|
180 |
- parent: ar |
|
181 |
id: ar_add_quotation |
|
182 |
name: Add Quotation |
|
183 |
icon: quotation_add |
|
184 |
order: 200 |
|
185 |
access: sales_quotation_edit |
|
186 |
module: oe.pl |
|
187 |
params: |
|
188 |
action: add |
|
189 |
type: sales_quotation |
|
190 |
- parent: ar |
|
191 |
id: ar_add_sales_order |
|
192 |
name: Add Sales Order |
|
193 |
icon: sales_order_add |
|
194 |
order: 300 |
|
195 |
access: sales_order_edit |
|
196 |
module: oe.pl |
|
197 |
params: |
|
198 |
action: add |
|
199 |
type: sales_order |
|
200 |
- parent: ar |
|
201 |
id: ar_add_delivery_order |
|
202 |
name: Add Delivery Order |
|
203 |
icon: delivery_order_add |
|
204 |
order: 400 |
|
205 |
access: sales_delivery_order_edit |
|
206 |
module: do.pl |
|
207 |
params: |
|
208 |
action: add |
|
209 |
type: sales_delivery_order |
|
210 |
- parent: ar |
|
211 |
id: ar_add_sales_invoice |
|
212 |
name: Add Sales Invoice |
|
213 |
icon: sales_invoice_add |
|
214 |
order: 500 |
|
215 |
access: invoice_edit |
|
216 |
module: is.pl |
|
217 |
params: |
|
218 |
action: add |
|
219 |
type: invoice |
|
220 |
- parent: ar |
|
221 |
id: ar_add_credit_note |
|
222 |
name: Add Credit Note |
|
223 |
icon: credit_note_add |
|
224 |
order: 600 |
|
225 |
access: invoice_edit |
|
226 |
module: is.pl |
|
227 |
params: |
|
228 |
action: add |
|
229 |
type: credit_note |
|
230 |
- parent: ar |
|
231 |
id: ar_add_dunning |
|
232 |
name: Add Dunning |
|
233 |
icon: dunning_add |
|
234 |
order: 700 |
|
235 |
access: dunning_edit |
|
236 |
module: dn.pl |
|
237 |
params: |
|
238 |
action: add |
|
239 |
- parent: ar |
|
240 |
id: ar_add_letter |
|
241 |
name: Add Letter |
|
242 |
order: 800 |
|
243 |
access: sales_letter_edit |
|
244 |
module: letter.pl |
|
245 |
params: |
|
246 |
action: add |
|
247 |
- parent: ar |
|
248 |
id: ar_reports |
|
249 |
name: Reports |
|
250 |
icon: ar_report |
|
251 |
order: 900 |
|
252 |
module: menu.pl |
|
253 |
params: |
|
254 |
action: acc_menu |
|
255 |
- parent: ar_reports |
|
256 |
id: ar_reports_requirement_specs |
|
257 |
name: Requirement Specs |
|
258 |
order: 100 |
|
259 |
access: requirement_spec_edit |
|
260 |
params: |
|
261 |
action: RequirementSpec/list |
|
262 |
- parent: ar_reports |
|
263 |
id: ar_reports_quotations |
|
264 |
name: Quotations |
|
265 |
icon: report_quotations |
|
266 |
order: 200 |
|
267 |
access: sales_quotation_edit |
|
268 |
module: oe.pl |
|
269 |
params: |
|
270 |
action: search |
|
271 |
type: sales_quotation |
|
272 |
- parent: ar_reports |
|
273 |
id: ar_reports_sales_orders |
|
274 |
name: Sales Orders |
|
275 |
icon: report_sales_orders |
|
276 |
order: 300 |
|
277 |
access: sales_order_edit |
|
278 |
module: oe.pl |
|
279 |
params: |
|
280 |
action: search |
|
281 |
type: sales_order |
|
282 |
- parent: ar_reports |
|
283 |
id: ar_reports_delivery_orders |
|
284 |
name: Delivery Orders |
|
285 |
icon: delivery_order_report |
|
286 |
order: 400 |
|
287 |
access: sales_delivery_order_edit |
|
288 |
module: do.pl |
|
289 |
params: |
|
290 |
action: search |
|
291 |
type: sales_delivery_order |
|
292 |
- parent: ar_reports |
|
293 |
id: ar_reports_invoices_credit_notes_ar_transactions |
|
294 |
name: Invoices, Credit Notes & AR Transactions |
|
295 |
icon: invoices_report |
|
296 |
order: 500 |
|
297 |
access: invoice_edit |
|
298 |
module: ar.pl |
|
299 |
params: |
|
300 |
action: search |
|
301 |
nextsub: ar_transactions |
|
302 |
- parent: ar_reports |
|
303 |
id: ar_reports_sales_report |
|
304 |
name: Sales Report |
|
305 |
order: 600 |
|
306 |
access: invoice_edit |
|
307 |
module: vk.pl |
|
308 |
params: |
|
309 |
action: search_invoice |
|
310 |
nextsub: invoice_transactions |
|
311 |
- parent: ar_reports |
|
312 |
id: ar_reports_dunnings |
|
313 |
name: Dunnings |
|
314 |
icon: dunnings_report |
|
315 |
order: 700 |
|
316 |
access: dunning_edit |
|
317 |
module: dn.pl |
|
318 |
params: |
|
319 |
action: search |
|
320 |
- parent: ar_reports |
|
321 |
id: ar_reports_delivery_plan |
|
322 |
name: Delivery Plan |
|
323 |
order: 800 |
|
324 |
access: delivery_plan |
|
325 |
params: |
|
326 |
action: DeliveryPlan/list |
|
327 |
vc: customer |
|
328 |
mode: delivery_plan |
|
329 |
- parent: ar_reports |
|
330 |
id: ar_reports_delivery_value_report |
|
331 |
name: Delivery Value Report |
|
332 |
order: 900 |
|
333 |
access: delivery_value_report |
|
334 |
params: |
|
335 |
action: DeliveryPlan/list |
|
336 |
mode: delivery_value_report |
|
337 |
vc: customer |
|
338 |
- parent: ar_reports |
|
339 |
id: ar_reports_financial_controlling |
|
340 |
name: Financial Controlling |
|
341 |
order: 1000 |
|
342 |
access: sales_order_edit |
|
343 |
params: |
|
344 |
action: FinancialControllingReport/list |
|
345 |
- parent: ar_reports |
|
346 |
id: ar_reports_letters |
|
347 |
name: Letters |
|
348 |
order: 1100 |
|
349 |
access: sales_letter_report |
|
350 |
module: letter.pl |
|
351 |
params: |
|
352 |
action: search |
|
353 |
- id: ap |
|
354 |
name: AP |
|
355 |
icon: ap |
|
356 |
order: 300 |
|
357 |
- parent: ap |
|
358 |
id: ap_add_rfq |
|
359 |
name: Add RFQ |
|
360 |
icon: rfq_add |
|
361 |
order: 100 |
|
362 |
access: request_quotation_edit |
|
363 |
module: oe.pl |
|
364 |
params: |
|
365 |
action: add |
|
366 |
type: request_quotation |
|
367 |
- parent: ap |
|
368 |
id: ap_add_purchase_order |
|
369 |
name: Add Purchase Order |
|
370 |
icon: purchase_order_add |
|
371 |
order: 200 |
|
372 |
access: purchase_order_edit |
|
373 |
module: oe.pl |
|
374 |
params: |
|
375 |
action: add |
|
376 |
type: purchase_order |
|
377 |
- parent: ap |
|
378 |
id: ap_add_delivery_note |
|
379 |
name: Add Delivery Note |
|
380 |
order: 300 |
|
381 |
access: client/allow_new_purchase_delivery_order & purchase_delivery_order_edit |
|
382 |
module: do.pl |
|
383 |
params: |
|
384 |
action: add |
|
385 |
type: purchase_delivery_order |
|
386 |
- parent: ap |
|
387 |
id: ap_add_vendor_invoice |
|
388 |
name: Add Vendor Invoice |
|
389 |
order: 400 |
|
390 |
access: client/allow_new_purchase_invoice & vendor_invoice_edit |
|
391 |
module: ir.pl |
|
392 |
params: |
|
393 |
action: add |
|
394 |
type: invoice |
|
395 |
- parent: ap |
|
396 |
id: ap_reports |
|
397 |
name: Reports |
|
398 |
icon: ap_report |
|
399 |
order: 500 |
|
400 |
module: menu.pl |
|
401 |
params: |
|
402 |
action: acc_menu |
|
403 |
- parent: ap_reports |
|
404 |
id: ap_reports_rfqs |
|
405 |
name: RFQs |
|
406 |
icon: rfq_report |
|
407 |
order: 100 |
|
408 |
access: request_quotation_edit |
|
409 |
module: oe.pl |
|
410 |
params: |
|
411 |
action: search |
|
412 |
type: request_quotation |
|
413 |
- parent: ap_reports |
|
414 |
id: ap_reports_purchase_orders |
|
415 |
name: Purchase Orders |
|
416 |
icon: purchase_order_report |
|
417 |
order: 200 |
|
418 |
access: purchase_order_edit |
|
419 |
module: oe.pl |
|
420 |
params: |
|
421 |
action: search |
|
422 |
type: purchase_order |
|
423 |
- parent: ap_reports |
|
424 |
id: ap_reports_delivery_orders |
|
425 |
name: Delivery Orders |
|
426 |
order: 300 |
|
427 |
access: purchase_delivery_order_edit |
|
428 |
module: do.pl |
|
429 |
params: |
|
430 |
action: search |
|
431 |
type: purchase_delivery_order |
|
432 |
- parent: ap_reports |
|
433 |
id: ap_reports_vendor_invoices_ap_transactions |
|
434 |
name: Vendor Invoices & AP Transactions |
|
435 |
order: 400 |
|
436 |
access: vendor_invoice_edit |
|
437 |
module: ap.pl |
|
438 |
params: |
|
439 |
action: search |
|
440 |
nextsub: ap_transactions |
|
441 |
- parent: ap_reports |
|
442 |
id: ap_reports_delivery_plan |
|
443 |
name: Delivery Plan |
|
444 |
order: 500 |
|
445 |
access: delivery_plan |
|
446 |
params: |
|
447 |
action: DeliveryPlan/list |
|
448 |
mode: delivery_plan |
|
449 |
vc: vendor |
|
450 |
- parent: ap_reports |
|
451 |
id: ap_reports_delivery_value_report |
|
452 |
name: Delivery Value Report |
|
453 |
order: 600 |
|
454 |
access: delivery_value_report |
|
455 |
params: |
|
456 |
action: DeliveryPlan/list |
|
457 |
vc: vendor |
|
458 |
mode: delivery_value_report |
|
459 |
- id: warehouse |
|
460 |
name: Warehouse |
|
461 |
icon: warehouse |
|
462 |
order: 400 |
|
463 |
- parent: warehouse |
|
464 |
id: warehouse_stock |
|
465 |
name: Stock |
|
466 |
order: 100 |
|
467 |
access: warehouse_management |
|
468 |
params: |
|
469 |
action: Inventory/stock_in |
|
470 |
- parent: warehouse |
|
471 |
id: warehouse_produce_assembly |
|
472 |
name: Produce Assembly |
|
473 |
icon: assembly_produce |
|
474 |
order: 200 |
|
475 |
access: warehouse_management |
|
476 |
module: wh.pl |
|
477 |
params: |
|
478 |
action: transfer_warehouse_selection |
|
479 |
trans_type: assembly |
|
480 |
- parent: warehouse |
|
481 |
id: warehouse_transfer |
|
482 |
name: Transfer |
|
483 |
order: 300 |
|
484 |
access: warehouse_management |
|
485 |
module: wh.pl |
|
486 |
params: |
|
487 |
action: transfer_warehouse_selection |
|
488 |
trans_type: transfer |
|
489 |
- parent: warehouse |
|
490 |
id: warehouse_removal |
|
491 |
name: Removal |
|
492 |
order: 400 |
|
493 |
access: warehouse_management |
|
494 |
module: wh.pl |
|
495 |
params: |
|
496 |
action: transfer_warehouse_selection |
|
497 |
trans_type: removal |
|
498 |
- parent: warehouse |
|
499 |
id: warehouse_reports |
|
500 |
name: Reports |
|
501 |
order: 500 |
|
502 |
module: menu.pl |
|
503 |
params: |
|
504 |
action: acc_menu |
|
505 |
- parent: warehouse_reports |
|
506 |
id: warehouse_reports_warehouse_content |
|
507 |
name: Warehouse content |
|
508 |
order: 100 |
|
509 |
access: warehouse_contents | warehouse_management |
|
510 |
module: wh.pl |
|
511 |
params: |
|
512 |
action: report |
|
513 |
- parent: warehouse_reports |
|
514 |
id: warehouse_reports_whjournal |
|
515 |
name: WHJournal |
|
516 |
order: 200 |
|
517 |
access: warehouse_management |
|
518 |
module: wh.pl |
|
519 |
params: |
|
520 |
action: journal |
|
521 |
- id: general_ledger |
|
522 |
name: General Ledger |
|
523 |
icon: gl |
|
524 |
order: 500 |
|
525 |
- parent: general_ledger |
|
526 |
id: general_ledger_add_transaction |
|
527 |
name: Add Transaction |
|
528 |
icon: transaction_add |
|
529 |
order: 100 |
|
530 |
access: general_ledger |
|
531 |
module: gl.pl |
|
532 |
params: |
|
533 |
action: add |
|
534 |
- parent: general_ledger |
|
535 |
id: general_ledger_add_ar_transaction |
|
536 |
name: Add AR Transaction |
|
537 |
icon: ar_transaction_add |
|
538 |
order: 200 |
|
539 |
access: general_ledger |
|
540 |
module: ar.pl |
|
541 |
params: |
|
542 |
action: add |
|
543 |
- parent: general_ledger |
|
544 |
id: general_ledger_add_ap_transaction |
|
545 |
name: Add AP Transaction |
|
546 |
icon: ap_transaction_add |
|
547 |
order: 300 |
|
548 |
access: general_ledger |
|
549 |
module: ap.pl |
|
550 |
params: |
|
551 |
action: add |
|
552 |
- parent: general_ledger |
|
553 |
id: general_ledger_datev_export_assistent |
|
554 |
name: DATEV - Export Assistent |
|
555 |
icon: datev |
|
556 |
order: 400 |
|
557 |
access: datev_export |
|
558 |
module: datev.pl |
|
559 |
params: |
|
560 |
action: export |
|
561 |
- parent: general_ledger |
|
562 |
id: general_ledger_reports |
|
563 |
name: Reports |
|
564 |
icon: gl_report |
|
565 |
order: 500 |
|
566 |
module: menu.pl |
|
567 |
params: |
|
568 |
action: acc_menu |
|
569 |
- parent: general_ledger_reports |
|
570 |
id: general_ledger_reports_ar_aging |
|
571 |
name: AR Aging |
|
572 |
icon: ar_aging |
|
573 |
order: 100 |
|
574 |
access: general_ledger |
|
575 |
module: rp.pl |
|
576 |
params: |
|
577 |
action: report |
|
578 |
report: ar_aging |
|
579 |
- parent: general_ledger_reports |
|
580 |
id: general_ledger_reports_ap_aging |
|
581 |
name: AP Aging |
|
582 |
icon: ap_aging |
|
583 |
order: 200 |
|
584 |
access: general_ledger |
|
585 |
module: rp.pl |
|
586 |
params: |
|
587 |
action: report |
|
588 |
report: ap_aging |
|
589 |
- parent: general_ledger_reports |
|
590 |
id: general_ledger_reports_journal |
|
591 |
name: Journal |
|
592 |
icon: journal |
|
593 |
order: 300 |
|
594 |
access: general_ledger |
|
595 |
module: gl.pl |
|
596 |
params: |
|
597 |
action: search |
|
598 |
- id: cash |
|
599 |
name: Cash |
|
600 |
icon: cash |
|
601 |
order: 600 |
|
602 |
- parent: cash |
|
603 |
id: cash_receipt |
|
604 |
name: Receipt |
|
605 |
icon: receipt |
|
606 |
order: 100 |
|
607 |
access: cash |
|
608 |
module: cp.pl |
|
609 |
params: |
|
610 |
action: payment |
|
611 |
vc: customer |
|
612 |
type: receipt |
|
613 |
- parent: cash |
|
614 |
id: cash_payment |
|
615 |
name: Payment |
|
616 |
icon: payment |
|
617 |
order: 200 |
|
618 |
access: cash |
|
619 |
module: cp.pl |
|
620 |
params: |
|
621 |
action: payment |
|
622 |
vc: vendor |
|
623 |
type: check |
|
624 |
- parent: cash |
|
625 |
id: cash_bank_collection_via_sepa |
|
626 |
name: Bank collection via SEPA |
|
627 |
order: 300 |
|
628 |
access: cash |
|
629 |
module: sepa.pl |
|
630 |
params: |
|
631 |
action: bank_transfer_add |
|
632 |
vc: customer |
|
633 |
- parent: cash |
|
634 |
id: cash_bank_transfer_via_sepa |
|
635 |
name: Bank transfer via SEPA |
|
636 |
order: 400 |
|
637 |
access: cash |
|
638 |
module: sepa.pl |
|
639 |
params: |
|
640 |
action: bank_transfer_add |
|
641 |
vc: vendor |
|
642 |
- parent: cash |
|
643 |
id: cash_bank_import |
|
644 |
name: Bank Import |
|
645 |
order: 500 |
|
646 |
module: menu.pl |
|
647 |
params: |
|
648 |
action: acc_menu |
|
649 |
- parent: cash_bank_import |
|
650 |
id: cash_bank_import_csv |
|
651 |
name: CSV |
|
652 |
order: 100 |
|
653 |
access: bank_transaction |
|
654 |
params: |
|
655 |
action: CsvImport/new |
|
656 |
profile.type: bank_transactions |
|
657 |
- parent: cash_bank_import |
|
658 |
id: cash_bank_import_mt940 |
|
659 |
name: MT940 |
|
660 |
order: 200 |
|
661 |
access: bank_transaction |
|
662 |
params: |
|
663 |
action: BankImport/upload_mt940 |
|
664 |
- parent: cash |
|
665 |
id: cash_bank_transactions_mt940 |
|
666 |
name: Bank transactions MT940 |
|
667 |
order: 600 |
|
668 |
access: bank_transaction |
|
669 |
params: |
|
670 |
action: BankTransaction/search |
|
671 |
- parent: cash |
|
672 |
id: cash_reconciliation_with_bank |
|
673 |
name: Reconciliation with bank |
|
674 |
order: 700 |
|
675 |
access: bank_transaction |
|
676 |
params: |
|
677 |
action: Reconciliation/search |
|
678 |
next_sub: Reconciliation/reconciliation |
|
679 |
- parent: cash |
|
680 |
id: cash_reconciliation |
|
681 |
name: Reconciliation |
|
682 |
icon: reconcilliation |
|
683 |
order: 800 |
|
684 |
access: cash |
|
685 |
module: rc.pl |
|
686 |
params: |
|
687 |
action: reconciliation |
|
688 |
- parent: cash |
|
689 |
id: cash_reports |
|
690 |
name: Reports |
|
691 |
icon: cash_report |
|
692 |
order: 900 |
|
693 |
module: menu.pl |
|
694 |
params: |
|
695 |
action: acc_menu |
|
696 |
- parent: cash_reports |
|
697 |
id: cash_reports_receipts |
|
698 |
name: Receipts |
|
699 |
icon: receipt_report |
|
700 |
order: 100 |
|
701 |
access: cash |
|
702 |
module: rp.pl |
|
703 |
params: |
|
704 |
action: report |
|
705 |
report: receipts |
|
706 |
- parent: cash_reports |
|
707 |
id: cash_reports_payments |
|
708 |
name: Payments |
|
709 |
icon: payment_report |
|
710 |
order: 200 |
|
711 |
access: cash |
|
712 |
module: rp.pl |
Auch abrufbar als: Unified diff
Menüstruktur auf YAML geändert