Gruppenverwaltung auf Controllermodel umgestellt
authorMoritz Bunkus <m.bunkus@linet-services.de>
Mon, 10 Jun 2013 16:17:41 +0000 (18:17 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 13 Jun 2013 14:31:36 +0000 (16:31 +0200)
Dabei auch Verknüpfung Gruppen <-> Mandanten implementiert.

SL/Controller/Admin.pm
SL/DB/AuthGroup.pm
bin/mozilla/admin.pl
bin/mozilla/admin_groups.pl [deleted file]
locale/de/all
templates/webpages/admin/delete_group_confirm.html [deleted file]
templates/webpages/admin/edit_group.html
templates/webpages/admin/edit_group_membership.html [deleted file]
templates/webpages/admin/edit_groups.html [deleted file]
templates/webpages/admin/edit_user.html
templates/webpages/admin/show.html

index 0eee2a0..6f9d224 100644 (file)
@@ -14,7 +14,7 @@ use SL::User;
 
 use Rose::Object::MakeMethods::Generic
 (
-  'scalar --get_set_init' => [ qw(client user nologin_file_name db_cfg all_dateformats all_numberformats all_countrycodes all_stylesheets all_menustyles all_clients all_groups all_users) ],
+  'scalar --get_set_init' => [ qw(client user group nologin_file_name db_cfg all_dateformats all_numberformats all_countrycodes all_stylesheets all_menustyles all_clients all_groups all_users all_rights is_locked) ],
 );
 
 __PACKAGE__->run_before(\&setup_layout);
@@ -95,10 +95,7 @@ sub action_show {
 
   $self->render(
     "admin/show",
-    CLIENTS => SL::DB::Manager::AuthClient->get_all_sorted,
-    USERS   => SL::DB::Manager::AuthUser->get_all_sorted,
-    LOCKED  => (-e $self->nologin_file_name),
-    title   => "kivitendo " . t8('Administration'),
+    title => "kivitendo " . t8('Administration'),
   );
 }
 
@@ -242,6 +239,57 @@ sub action_test_database_connectivity {
                 error => $error);
 }
 
+#
+# actions: groups
+#
+
+sub action_new_group {
+  my ($self) = @_;
+
+  $self->group(SL::DB::AuthGroup->new);
+  $self->edit_group_form(title => t8('Create a new group'));
+}
+
+sub action_edit_group {
+  my ($self) = @_;
+  $self->edit_group_form(title => t8('Edit User Group'));
+}
+
+sub action_save_group {
+  my ($self) = @_;
+
+  my $params = delete($::form->{group}) || { };
+  my $is_new = !$params->{id};
+
+  $self->group($is_new ? SL::DB::AuthGroup->new : SL::DB::AuthGroup->new(id => $params->{id})->load)->assign_attributes(%{ $params });
+
+  my @errors = $self->group->validate;
+
+  if (@errors) {
+    flash('error', @errors);
+    $self->edit_group_form(title => $is_new ? t8('Create a new user group') : t8('Edit User Group'));
+    return;
+  }
+
+  $self->group->save;
+
+  flash_later('info', $is_new ? t8('The user group has been created.') : t8('The user group has been saved.'));
+  $self->redirect_to(action => 'show');
+}
+
+sub action_delete_group {
+  my ($self) = @_;
+
+  if (!$self->group->delete) {
+    flash('error', t8('The user group could not be deleted.'));
+    $self->edit_group_form(title => t8('Edit User Group'));
+    return;
+  }
+
+  flash_later('info', t8('The user group has been deleted.'));
+  $self->redirect_to(action => 'show');
+}
+
 #
 # actions: locking, unlocking
 #
@@ -273,8 +321,10 @@ sub action_lock_system {
 
 sub init_db_cfg            { $::lx_office_conf{'authentication/database'}                                            }
 sub init_nologin_file_name { $::lx_office_conf{paths}->{userspath} . '/nologin';                                     }
+sub init_is_locked         { -e $_[0]->nologin_file_name                                                             }
 sub init_client            { SL::DB::AuthClient->new(id => ($::form->{id} || ($::form->{client} || {})->{id}))->load }
 sub init_user              { SL::DB::AuthUser  ->new(id => ($::form->{id} || ($::form->{user}   || {})->{id}))->load }
+sub init_group             { SL::DB::AuthGroup ->new(id => ($::form->{id} || ($::form->{group}  || {})->{id}))->load }
 sub init_all_clients       { SL::DB::Manager::AuthClient->get_all_sorted                                             }
 sub init_all_users         { SL::DB::Manager::AuthUser->get_all_sorted                                               }
 sub init_all_groups        { SL::DB::Manager::AuthGroup->get_all_sorted                                              }
@@ -289,6 +339,27 @@ sub init_all_menustyles    {
   ];
 }
 
+sub init_all_rights {
+  my (@sections, $current_section);
+
+  foreach my $entry ($::auth->all_rights_full) {
+    if ($entry->[0] =~ m/^--/) {
+      push @sections, { description => $entry->[1], rights => [] };
+
+    } elsif (@sections) {
+      push @{ $sections[-1]->{rights} }, {
+        name        => $entry->[0],
+        description => $entry->[1],
+      };
+
+    } else {
+      die "Right without sections: " . join('::', @{ $entry });
+    }
+  }
+
+  return \@sections;
+}
+
 sub init_all_countrycodes {
   my %cc = User->country_codes;
   return [ map { id => $_, title => $cc{$_} }, sort { $cc{$a} cmp $cc{$b} } keys %cc ];
@@ -310,6 +381,13 @@ sub setup_layout {
 # displaying forms
 #
 
+sub use_multiselect_js {
+  my ($self) = @_;
+
+  $::request->layout->use_javascript("${_}.js") for qw(jquery.selectboxes jquery.multiselect2side);
+  return $self;
+}
+
 sub login_form {
   my ($self, %params) = @_;
   $::request->layout->focus('#admin_password');
@@ -318,16 +396,17 @@ sub login_form {
 
 sub edit_user_form {
   my ($self, %params) = @_;
-
-  $::request->layout->use_javascript("${_}.js") for qw(jquery.selectboxes jquery.multiselect2side);
-  $self->render('admin/edit_user', %params);
+  $self->use_multiselect_js->render('admin/edit_user', %params);
 }
 
 sub edit_client_form {
   my ($self, %params) = @_;
+  $self->use_multiselect_js->render('admin/edit_client', %params);
+}
 
-  $::request->layout->use_javascript("${_}.js") for qw(jquery.selectboxes jquery.multiselect2side);
-  $self->render('admin/edit_client', %params);
+sub edit_group_form {
+  my ($self, %params) = @_;
+  $self->use_multiselect_js->render('admin/edit_group', %params);
 }
 
 #
index 2bb168e..23dabb5 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 
 use SL::DB::MetaSetup::AuthGroup;
 use SL::DB::Manager::AuthGroup;
-use SL::DB::AuthGroupRight;
+use SL::DB::Helper::Util;
 
 __PACKAGE__->meta->add_relationship(
   users => {
@@ -28,9 +28,90 @@ __PACKAGE__->meta->add_relationship(
 
 __PACKAGE__->meta->initialize;
 
+sub validate {
+  my ($self) = @_;
+
+  my @errors;
+  push @errors, $::locale->text('The name is missing.')    if !$self->name;
+  push @errors, $::locale->text('The name is not unique.') if !SL::DB::Helper::Util::is_unique($self, 'name');
+
+  return @errors;
+}
+
 sub get_employees {
   my @logins = map { $_->login } $_[0]->users;
   return @logins ? @{ SL::DB::Manager::Employee->get_all(query => [ login => \@logins ]) } : ();
 }
 
+sub rights_map {
+  my $self = shift;
+
+  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() ]);
+  }
+
+  return {
+    map({ ($_        => 0)           } SL::Auth::all_rights()),
+    map({ ($_->right => $_->granted) } @{ $self->rights || [] })
+  };
+}
+
 1;
+__END__
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+SL::DB::AuthGroup - RDBO model for auth.group
+
+=head1 SYNOPSIS
+
+  # Outputting all rights granted to this group:
+  my $group  = SL::DB::Manager::AuthGroup->get_first;
+  my %rights = %{ $group->rights_map };
+  print "Granted rights:\n";
+  print "  $_\n" for sort grep { $rights{$_} } keys %rights;
+
+  # Set a right to 'yes':
+  $group->rights_map(%{ $group->rights_map }, invoice_edit => 1);
+  $group->save;
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item C<get_employees>
+
+Returns all employees (as instances of L<SL::DB::Employee>) whose
+corresponding logins are members in this group.
+
+=item C<rights_map [$new_rights]>
+
+Gets/sets the rights for this group as hashes. Returns a hash
+references containing the right names as the keys and trueish/falsish
+values for 'granted'/'not granted'.
+
+If C<$new_rights> is given as a hash reference or a plain hash then it
+will also set all rights from this hash.
+
+=item C<validate>
+
+Validates the object before saving (checks uniqueness, attribute
+presence etc). Returns a list of human-readable errors and an empty
+list on success.
+
+=back
+
+=head1 BUGS
+
+Nothing here yet.
+
+=head1 AUTHOR
+
+Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
+
+=cut
index 45da2f9..e069476 100755 (executable)
@@ -60,7 +60,6 @@ use SL::DBUtils;
 use SL::Template;
 
 require "bin/mozilla/common.pl";
-require "bin/mozilla/admin_groups.pl";
 require "bin/mozilla/admin_printer.pl";
 
 use strict;
diff --git a/bin/mozilla/admin_groups.pl b/bin/mozilla/admin_groups.pl
deleted file mode 100644 (file)
index 1444332..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-#=====================================================================
-# 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) 2002
-#
-#  Author: Moritz Bunkus
-#   Email: mbunkus@linet-services.de
-#     Web: www.linet-services.de
-#
-#
-# 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.
-#======================================================================
-#
-# group administration module
-# add/edit/delete user groups
-#
-#======================================================================
-
-use List::MoreUtils qw(uniq);
-
-use strict;
-
-sub edit_groups {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-
-  my @groups = sort { lc $a->{name} cmp lc $b->{name} } values %{ $main::auth->read_groups() };
-
-  $form->header();
-  print $form->parse_html_template("admin/edit_groups", { 'GROUPS'     => \@groups,
-                                                          'num_groups' => scalar @groups });
-
-  $main::lxdebug->leave_sub();
-}
-
-sub add_group {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-
-  delete $form->{group_id};
-  $form->{message} = $locale->text("The group has been added.");
-
-  save_group();
-
-  $main::lxdebug->leave_sub();
-}
-
-sub save_group {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-
-  $form->isblank('name', $locale->text('The group name is missing.'));
-
-  my $groups = $main::auth->read_groups();
-  my %users  = map { ( $_->{id} => 1 ) } values %{ { $::auth->read_all_users() } };
-
-  foreach my $group (values %{$groups}) {
-    if (($form->{group_id} != $group->{id})
-        && ($form->{name} eq $group->{name})) {
-      $form->show_generic_error($locale->text("A group with that name does already exist."));
-    }
-  }
-
-  my $group;
-
-  if ($form->{group_id} && $groups->{$form->{group_id}}) {
-    $group = $groups->{$form->{group_id}};
-
-  } else {
-    $group = { };
-  }
-
-  $group->{name}        = $form->{name};
-  $group->{description} = $form->{description};
-  $group->{rights}      = { map { ( $_ => $form->{"${_}_granted"} ? 1 : 0 ) } SL::Auth::all_rights() };
-  $group->{members}     = [ grep { $users{$_} } @{ $form->{user_ids} || [] } ];
-
-  my $is_new = !$form->{group_id};
-
-  $main::auth->save_group($group);
-
-  $form->{message} ||= $locale->text('The group has been saved.');
-
-  if ($is_new) {
-    edit_groups();
-
-  } else {
-    edit_group();
-  }
-
-  $main::lxdebug->leave_sub();
-}
-
-sub edit_group {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-
-  my $groups = $main::auth->read_groups();
-
-  if (!$form->{group_id} || !$groups->{$form->{group_id}}) {
-    $form->show_generic_error($locale->text("No group has been selected, or the group does not exist anymore."));
-  }
-
-  my $group     = $groups->{$form->{group_id}};
-  my %all_users = $main::auth->read_all_users();
-  my @rights    = map {
-    { "right"       => $_->[0],
-      "description" => $_->[1],
-      "is_section"  => '--' eq substr($_->[0], 0, 2),
-      "granted"     => defined $group->{rights}->{$_->[0]} ? $group->{rights}->{$_->[0]} : 0,
-    }
-  } SL::Auth::all_rights_full();
-
-  $form->header();
-  print $form->parse_html_template("admin/edit_group", { ALL_USERS            => [ values %all_users ],
-                                                         USER_IDS_IN_GROUP    => $group->{members},
-                                                         "RIGHTS"             => \@rights,
-                                                         "name"               => $group->{name},
-                                                         "description"        => $group->{description} });
-
-  $main::lxdebug->leave_sub();
-}
-
-sub delete_group {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-
-  my $groups = $main::auth->read_groups();
-
-  if (!$form->{group_id} || !$groups->{$form->{group_id}}) {
-    $form->show_generic_error($locale->text("No group has been selected, or the group does not exist anymore."));
-  }
-
-  if ($form->{confirmed}) {
-    $main::auth->delete_group($form->{"group_id"});
-
-    $form->{message} = $locale->text("The group has been deleted.");
-    edit_groups();
-
-  } else {
-
-    $form->header();
-    print $form->parse_html_template("admin/delete_group_confirm", $groups->{$form->{group_id}});
-  }
-
-  $main::lxdebug->leave_sub();
-}
-
-sub edit_group_membership {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-
-  my %users  = $main::auth->read_all_users();
-  my $groups = $main::auth->read_groups();
-  $groups    = [ sort { lc $a->{name} cmp lc $b->{name} } values %{ $groups } ];
-
-  my @headings = map { { 'title' => $_ } } map { $_->{name} } @{ $groups };
-
-  foreach my $group (@{ $groups }) {
-    $group->{members_h} = { map { $_ => 1 } @{ $group->{members} } };
-  }
-
-  my @rows;
-
-  foreach my $user (sort { lc $a->{login} cmp lc $b->{login} } values %users) {
-    my $row = {
-      'id'              => $user->{id},
-      'login'           => $user->{login},
-      'name'            => $user->{name},
-      'repeat_headings' => (scalar(@rows) % 20) == 0,
-      'GROUPS'          => [],
-    };
-
-    foreach my $group (@{ $groups }) {
-      push @{ $row->{GROUPS} }, {
-        'id'        => $group->{id},
-        'is_member' => $group->{members_h}->{$user->{id}},
-      };
-    }
-
-    push @rows, $row;
-  }
-
-  $form->{title} = $locale->text('Edit group membership');
-  $form->header();
-  print $form->parse_html_template('admin/edit_group_membership', { 'HEADINGS' => \@headings, 'USERS' => \@rows });
-
-  $main::lxdebug->leave_sub();
-}
-
-sub save_group_membership {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-
-  my %users  = $main::auth->read_all_users();
-  my $groups = $main::auth->read_groups();
-
-  foreach my $group (values %{ $groups }) {
-    $group->{members} = [ ];
-
-    foreach my $user (values %users) {
-      push @{ $group->{members} }, $user->{id} if ($form->{"u_$user->{id}_g_$group->{id}"});
-    }
-
-    $main::auth->save_group($group);
-  }
-
-  $form->{message} = $locale->text('The group memberships have been saved.');
-
-  edit_groups();
-
-  $main::lxdebug->leave_sub();
-}
-
-1;
index 58736b7..5103526 100755 (executable)
@@ -42,7 +42,6 @@ $self->{texts} = {
   '<b>What</b> do you want to look for?' => '<b>Wonach</b> wollen Sie suchen?',
   'A Buchungsgruppe consists of a descriptive name and the account numbers for the income and expense accounts for those four tax zones as well as the inventory account number.' => 'Eine Buchungsgruppe besteht aus einem deskriptiven Namen, den Erl&ouml;s- und Aufwandskonten f&uuml;r diese vier Steuerzonen sowie aus einem Inventarkonto.',
   'A digit is required.'        => 'Eine Ziffer ist vorgeschrieben.',
-  'A group with that name does already exist.' => 'Eine Gruppe mit diesem Namen gibt es bereits.',
   'A lot of the usability of kivitendo has been enhanced with javascript. Although it is currently possible to use every aspect of kivitendo without javascript, we strongly recommend it. In a future version this may change and javascript may be necessary to access advanced features.' => 'Die Bedienung von kivitendo wurde an vielen Stellen mit Javascript verbessert. Obwohl es derzeit möglich ist, jeden Aspekt von kivitendo auch ohne Javascript zu benutzen, empfehlen wir es. In einer zukünftigen Version wird Javascript eventuell notwendig sein um weitergehende Features zu benutzen.',
   'A lower-case character is required.' => 'Ein Kleinbuchstabe ist vorgeschrieben.',
   'A special character is required (valid characters: #1).' => 'Ein Sonderzeichen ist vorgeschrieben (gültige Zeichen: #1).',
@@ -75,6 +74,7 @@ $self->{texts} = {
   'Abort'                       => 'Abbrechen',
   'Abrechnungsnummer'           => 'Abrechnungsnummer',
   'Abteilung'                   => 'Abteilung',
+  'Access rights'               => 'Zugriffsrechte',
   'Access to clients'           => 'Zugriff auf Mandanten',
   'Account'                     => 'Konto',
   'Account Category A'          => 'Aktiva/Mittelverwendung',
@@ -159,10 +159,10 @@ $self->{texts} = {
   'Add Storno Credit Note'      => 'Gutschrift Storno hinzufügen',
   'Add Transaction'             => 'Dialogbuchen',
   'Add User'                    => 'Neuer Benutzer',
+  'Add User Group'              => 'Neue Benutzergruppe',
   'Add Vendor'                  => 'Lieferant erfassen',
   'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
   'Add Warehouse'               => 'Lager erfassen',
-  'Add a new group'             => 'Neue Gruppe erfassen',
   'Add and edit units'          => 'Einheiten erfassen und bearbeiten',
   'Add bank account'            => 'Bankkonto erfassen',
   'Add custom variable'         => 'Benutzerdefinierte Variable erfassen',
@@ -443,6 +443,7 @@ $self->{texts} = {
   'Client Configuration saved!' => 'Mandantenkonfiguration gespeichert!',
   'Client list'                 => 'Mandantenliste',
   'Client name'                 => 'Mandantenname',
+  'Clients this Group is valid for' => 'Mandanten, für die diese Gruppe gültig ist',
   'Clients this user has access to' => 'Mandaten, auf die Benutzer Zugriff hat',
   'Close'                       => 'Übernehmen',
   'Close Books up to'           => 'Die Bücher abschließen bis zum',
@@ -497,9 +498,11 @@ $self->{texts} = {
   'Create a new business'       => 'Einen neuen Kunden-/Lieferantentyp erfassen',
   'Create a new client'         => 'Einen neuen Mandanten anlegen',
   'Create a new department'     => 'Eine neue Abteilung erfassen',
+  'Create a new group'          => 'Neue Benutzergruppe erfassen',
   'Create a new payment term'   => 'Neue Zahlungsbedingungen anlegen',
   'Create a new project'        => 'Neues Projekt anlegen',
   'Create a new user'           => 'Einen neuen Benutzer anlegen',
+  'Create a new user group'     => 'Eine neue Benutzergruppe erfassen',
   'Create and edit RFQs'        => 'Lieferantenanfragen erfassen und bearbeiten',
   'Create and edit dunnings'    => 'Mahnungen erfassen und bearbeiten',
   'Create and edit invoices and credit notes' => 'Rechnungen und Gutschriften erfassen und bearbeiten',
@@ -652,7 +655,6 @@ $self->{texts} = {
   'Delete Shipto'               => 'Lieferadresse löschen',
   'Delete delivery order'       => 'Lieferschein l&ouml;schen',
   'Delete drafts'               => 'Entwürfe löschen',
-  'Delete group'                => 'Gruppe l&ouml;schen',
   'Delete links'                => 'Verknüpfungen löschen',
   'Delete profile'              => 'Profil löschen',
   'Delete transaction'          => 'Buchung löschen',
@@ -704,7 +706,6 @@ $self->{texts} = {
   'Do you really want to delete AR transaction #1?' => 'Wollen Sie wirklich die Debitorenbuchung #1 löschen?',
   'Do you really want to delete GL transaction #1?' => 'Wollen Sie wirklich die Dialogbuchung #1 löschen?',
   'Do you really want to delete the selected links?' => 'Wollen Sie wirklich die ausgewählten Verknüpfungen löschen?',
-  'Do you really want to delete this group?' => 'Gruppe wirklich l&ouml;schen?',
   'Do you really want to delete this object?' => 'Wollen Sie dieses Objekt wirklich löschen?',
   'Do you really want to delete this warehouse?' => 'Wollen Sie dieses Lager wirklich l&ouml;schen?',
   'Do you want to <b>limit</b> your search?' => 'Wollen Sie Ihre Suche <b>spezialisieren</b>?',
@@ -802,10 +803,10 @@ $self->{texts} = {
   'Edit Storno Credit Note'     => 'Storno Gutschrift bearbeiten',
   'Edit Storno Invoice'         => 'Stornorechnung bearbeiten',
   'Edit User'                   => 'Benutzerdaten bearbeiten',
+  'Edit User Group'             => 'Benutzergruppe bearbeiten',
   'Edit Vendor'                 => 'Lieferant editieren',
   'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
   'Edit Warehouse'              => 'Lager bearbeiten',
-  'Edit and delete a group'     => 'Gruppen bearbeiten und l&ouml;schen',
   'Edit background job'         => 'Hintergrund-Job bearbeiten',
   'Edit bank account'           => 'Bankkonto bearbeiten',
   'Edit business'               => 'Kunden-/Lieferantentyp bearbeiten',
@@ -813,20 +814,14 @@ $self->{texts} = {
   'Edit department'             => 'Abteilung bearbeiten',
   'Edit file'                   => 'Datei bearbeiten',
   'Edit greetings'              => 'Anreden bearbeiten',
-  'Edit group '                 => 'Gruppe bearbeiten',
-  'Edit group membership'       => 'Gruppenmitgliedschaften bearbeiten',
-  'Edit groups'                 => 'Gruppen bearbeiten',
-  'Edit membership'             => 'Mitgliedschaft bearbeiten',
   'Edit note'                   => 'Notiz bearbeiten',
   'Edit payment term'           => 'Zahlungsbedingungen bearbeiten',
   'Edit prices and discount (if not used, textfield is ONLY set readonly)' => 'Preise und Rabatt in Formularen frei anpassen (falls deaktiviert, wird allerdings NUR das textfield auf READONLY gesetzt / kann je nach Browserversion und technischen Fähigkeiten des Anwenders noch umgangen werden)',
   'Edit project'                => 'Projekt bearbeiten',
   'Edit project #1'             => 'Projekt #1 bearbeiten',
-  'Edit rights'                 => 'Rechte bearbeiten',
   'Edit templates'              => 'Vorlagen bearbeiten',
   'Edit the Delivery Order'     => 'Lieferschein bearbeiten',
   'Edit the configuration for periodic invoices' => 'Konfiguration für wiederkehrende Rechnungen bearbeiten',
-  'Edit the membership of all users in all groups:' => 'Bearbeiten der Mitgliedschaft aller Benutzer in allen Gruppen:',
   'Edit the purchase_order'     => 'Bearbeiten des Lieferantenauftrags',
   'Edit the request_quotation'  => 'Bearbeiten der Preisanfrage',
   'Edit the sales_order'        => 'Bearbeiten des Auftrags',
@@ -995,6 +990,7 @@ $self->{texts} = {
   'Group Items'                 => 'Waren gruppieren',
   'Group assignment'            => 'Gruppenzuordnung',
   'Group deleted!'              => 'Warengruppe gelöscht!',
+  'Group list'                  => 'Gruppenliste',
   'Group membership'            => 'Gruppenzugehörigkeit',
   'Group missing!'              => 'Warengruppe fehlt!',
   'Group saved!'                => 'Warengruppe gespeichert!',
@@ -1055,7 +1051,7 @@ $self->{texts} = {
   'Import result'               => 'Import-Ergebnis',
   'Import summary'              => 'Import-Zusammenfassung',
   'In order to do that hit the button "Delete transaction".' => 'Drücken Sie dafür auf den Button "Buchung löschen".',
-  'In order to use kivitendo you have to create at least one client, one user, and grant that user access to the client.' => 'Um kivitendo zu nutzen, müssen Sie mindestens einen Mandanten und einen Benutzer anlegen sowie dem Benutzer den Zugriff auf diesen Mandanten gewähren.',
+  'In order to use kivitendo you have to create at least a client, a user and a group.' => 'Um kivitendo zu nutzen, müssen Sie mindestens einen Mandanten, einen Benutzer und eine Gruppe anlegen.',
   'In the latter case the tables needed by kivitendo will be created in that database.' => 'In letzterem Fall werden die von kivitendo benötigten Tabellen in dieser existierenden Datenbank angelegt.',
   'In version 2.4.0 the administrator has to enter a list of units in the administrative section.' => 'Vor Version 2.4.0 musste der Benutzer die Konten bei jeder Ware und jeder Dienstleistung einzeln ausw&auml;hlen.',
   'In-line'                     => 'im Text',
@@ -1337,8 +1333,6 @@ $self->{texts} = {
   'No dunnings have been selected for printing.' => 'Es wurden keine Mahnungen zum Drucken ausgew&auml;hlt.',
   'No entries were found which had no unit assigned to them.' => 'Es wurden keine Eintr&auml;ge gefunden, denen keine Einheit zugeordnet war.',
   'No file has been uploaded yet.' => 'Es wurde noch keine Datei hochgeladen.',
-  'No group has been selected, or the group does not exist anymore.' => 'Es wurde keine Gruppe ausgew&auml;hlt, oder die Gruppe wurde in der Zwischenzeit gel&ouml;scht.',
-  'No groups have been added yet.' => 'Es wurden noch keine Gruppen angelegt.',
   'No groups have been created yet.' => 'Es wurden noch keine Gruppen angelegt.',
   'No or an unknown authenticantion module specified in "config/kivitendo.conf".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/kivitendo.conf" angegeben.',
   'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
@@ -1510,6 +1504,7 @@ $self->{texts} = {
   'Please enter the currency you are working with.' => 'Bitte geben Sie die Währung an, mit der Sie arbeiten.',
   'Please enter the login for the new user.' => 'Bitte geben Sie das Login für den neuen Benutzer ein.',
   'Please enter the name for the new client.' => 'Bitte geben Sie einen Namen für den neuen Mandanten ein.',
+  'Please enter the name for the new group.' => 'Bitte geben Sie den Namen für die neue Gruppe ein.',
   'Please enter the name of the database that will be used as the template for the new database:' => 'Bitte geben Sie den Namen der Datenbank an, die als Vorlage f&uuml;r die neue Datenbank benutzt wird:',
   'Please enter the name of the dataset you want to restore the backup in.' => 'Bitte geben Sie den Namen der Datenbank ein, in der Sie die Sicherung wiederherstellen wollen.',
   'Please enter the sales tax identification number.' => 'Bitte geben Sie die Umsatzsteueridentifikationsnummer an.',
@@ -1671,7 +1666,6 @@ $self->{texts} = {
   'Remove draft when posting'   => 'Entwurf beim Buchen l&ouml;schen',
   'Removed spoolfiles!'         => 'Druckdateien entfernt!',
   'Removing marked entries from queue ...' => 'Markierte Einträge werden von der Warteschlange entfernt ...',
-  'Rename the group'            => 'Gruppe umbenennen',
   'Replace the orphaned currencies by other not orphaned currencies. To do so, please delete the currency in the textfields above and replace it by another currency. You could loose or change unintentionally exchangerates. Go on very carefully since you could destroy transactions.' => 'Ersetze die Währungen durch andere gültige Währungen. Wenn Sie sich hierfür entscheiden, ersetzen Sie bitte alle Währungen, die oben angegeben sind, durch Währungen, die in Ihrem System ordnungsgemäß eingetragen sind. Alle eingetragenen Wechselkurse für die verwaiste Währung werden dabei gelöscht. Bitte gehen Sie sehr vorsichtig vor, denn die betroffenen Buchungen können unter Umständen kaputt gehen.',
   'Report Positions'            => 'Berichte',
   'Report about warehouse contents' => 'Lagerbestand anzeigen',
@@ -1768,6 +1762,7 @@ $self->{texts} = {
   'Search term'                 => 'Suchbegriff',
   'Searchable'                  => 'Durchsuchbar',
   'Secondary sorting'           => 'Untersortierung',
+  'Section "#1"'                => 'Abschnitt "#1"',
   'Select'                      => 'auswählen',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
@@ -1783,7 +1778,6 @@ $self->{texts} = {
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
   'Select tax office...'        => 'Finanzamt auswählen...',
   'Select the chart of accounts in use' => 'Benutzten Kontenrahmen ausw&auml;hlen',
-  'Select the checkboxes that match users to the groups they should belong to.' => 'W&auml;hlen Sie diejenigen Checkboxen aus, die die Benutzer zu den gew&uuml;schten Gruppen zuordnen.',
   'Select type of removal'      => 'Grund der Entnahme ausw&auml;hlen',
   'Select type of transfer'     => 'Grund der Umlagerung ausw&auml;hlen',
   'Selected'                    => 'Ausgewählt',
@@ -2029,7 +2023,7 @@ $self->{texts} = {
   'The column "make_X" can contain either a vendor\'s database ID, a vendor number or a vendor\'s name.' => 'Die Spalte "make_X" can entweder die Datenbank-ID des Lieferanten, eine Lieferantennummer oder einen Lieferantennamen enthalten.',
   'The column triplets can occur multiple times with different numbers "X" each time (e.g. "make_1", "model_1", "lastcost_1", "make_2", "model_2", "lastcost_2", "make_3", "model_3", "lastcost_3" etc).' => 'Die Spalten-Dreiergruppen können mehrfach auftreten, sofern sie unterschiedliche Nummern "X" verwenden (z.B. "make_1", "model_1", "lastcost_1", "make_2", "model_2", "lastcost_2", "make_3", "model_3", "lastcost_3" etc).',
   'The columns &quot;Dunning Duedate&quot;, &quot;Total Fees&quot; and &quot;Interest&quot; show data for the previous dunning created for this invoice.' => 'Die Spalten &quot;Zahlbar bis&quot;, &quot;Kumulierte Geb&uuml;hren&quot; und &quot;Zinsen&quot; zeigen Daten der letzten f&uuml;r diese Rechnung erzeugten Mahnung.',
-  'The combination of database host, port and name is not unique.' => '',
+  'The combination of database host, port and name is not unique.' => 'Die Kombination aus Datenbankhost, -port und -name ist nicht eindeutig.',
   'The connection to the LDAP server cannot be encrypted (SSL/TLS startup failure). Please check config/kivitendo.conf.' => 'Die Verbindung zum LDAP-Server kann nicht verschl&uuml;sselt werden (Fehler bei SSL/TLS-Initialisierung). Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/kivitendo.conf.',
   'The connection to the authentication database failed:' => 'Die Verbindung zur Authentifizierungsdatenbank schlug fehl:',
   'The connection to the configured client database "#1" on host "#2:#3" failed.' => 'Die Verbindung zur konfigurierten Datenbank "#1" auf Host "#2:#3" schlug fehl.',
@@ -2089,15 +2083,11 @@ $self->{texts} = {
   'The following transactions are concerned:' => 'Die folgenden Buchungen sind betroffen:',
   'The following units are unknown.' => 'Die folgenden Einheiten sind unbekannt.',
   'The following units exist already:' => 'Die folgenden Einheiten existieren bereits:',
+  'The following users are a member of this group' => 'Die folgenden Benutzer sind Mitglieder dieser Gruppe',
   'The following users will have access to this client' => 'Die folgenden Benutzer werden auf diesen Mandanten Zugriff haben',
   'The following warnings occured during an upgrade to the document templates:' => 'Die folgenden Warnungen traten w&auml;hrend einer Aktualisierung der Dokumentenvorlagen auf:',
   '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>' => 'Die Formeln m&uuml;ssen in der folgenden Syntax eingegeben werden:<br>Bei normalen Artikeln:<br>Variablenname = Variable Einheit;<br>Variablenname2 = Variable2 Einheit2;<br>...<br>###<br>Variable + Variable2 * ( Variable - Variable2 )<br>Variablennamen und Einheiten dürfen nur aus alphanumerischen Zeichen bestehen.<br>Es muss jeweils die Gesamte Zeile eingegeben werden',
   'The greetings have been saved.' => 'Die Anreden wurden gespeichert',
-  'The group has been added.'   => 'Die Gruppe wurde erfasst.',
-  'The group has been deleted.' => 'Die Gruppe wurde gel&ouml;scht.',
-  'The group has been saved.'   => 'Die Gruppe wurde gespeichert.',
-  'The group memberships have been saved.' => 'Die Gruppenmitgliedschaften wurden gespeichert.',
-  'The group name is missing.'  => 'Der Gruppenname fehlt.',
   'The items are imported accoring do their number "X" regardless of the column order inside the file.' => 'Die Einträge werden in der Reihenfolge ihrer Indizes "X" unabhängig von der Spaltenreihenfolge in der Datei importiert.',
   'The link target to add has been created from the existing record.' => 'Das auszuwählende Verknüpfungsziel wurde aus dem bestehenden Beleg erstellt.',
   'The list has been printed.'  => 'Die Liste wurde ausgedruckt.',
@@ -2170,6 +2160,10 @@ $self->{texts} = {
   'The units have been saved.'  => 'Die Einheiten wurden gespeichert.',
   'The user can chose which client to connect to during login.' => 'Bei der Anmeldung kann der Benutzer auswählen, welchen Mandanten er benutzen möchte.',
   'The user could not be deleted.' => 'Der Benutzer konnte nicht gelöscht werden.',
+  'The user group could not be deleted.' => 'Die Benutzergurppe konnte nicht gelöscht werden.',
+  'The user group has been created.' => 'Die Benutzergruppe wurde erstellt.',
+  'The user group has been deleted.' => 'Die Benutzergruppe wurde gelöscht.',
+  'The user group has been saved.' => 'Die Benutzergruppe wurde gespeichert.',
   'The user has been created.'  => 'Der Benutzer wurde angelegt.',
   'The user has been deleted.'  => 'Der Benutzer wurde gelöscht.',
   'The user has been saved.'    => 'Der Benutzer wurde gespeichert.',
@@ -2218,6 +2212,7 @@ $self->{texts} = {
   'This could have happened for two reasons:' => 'Dies kann aus zwei Gründen geschehen sein:',
   'This customer number is already in use.' => 'Diese Kundennummer wird bereits verwendet.',
   'This feature especially prevents mistakes by mixing up prior tax and sales tax.' => 'Dieses Feature vermeidet insbesondere Verwechslungen von Umsatz- und Vorsteuer.',
+  'This group is valid for the following clients' => 'Diese Gruppe ist für die folgenden Mandanten gültig',
   'This has been changed in this version, therefore please change the "old" bins to some real warehouse bins.' => 'Das wurde in dieser Version umgestellt, bitte ändern Sie die Freitext-Lagerplätze auf vorhandene Lagerplätze.',
   'This has been changed in this version.' => 'Ab dieser Version ist dies nicht mehr so.',
   'This installation uses an unknown chart of accounts (&quot;#1&quot;). This database upgrade cannot create standard buchungsgruppen automatically.' => 'Diese Installation benutzt einen unbekannten Kontenrahmen (&quot;#1&quot;). Dieses Datenbankupgrade kann die Standardbuchungsgruppen nicht automatisch anlegen.',
@@ -2351,7 +2346,7 @@ $self->{texts} = {
   'User login'                  => 'Benutzeranmeldung',
   'User name'                   => 'Benutzername',
   'Username'                    => 'Benutzername',
-  'Users in this group'         => 'BenutzerInnen in dieser Gruppe',
+  'Users that are a member in this group' => 'Gruppenmitglieder',
   'Users that have access to this client' => 'Benutzer mit Zugriff auf diesen Mandaten',
   'Users with access'           => 'Benutzer mit Zugriff',
   'Users with access to this client' => 'Benutzer mit Zugriff auf diesen Mandanten',
diff --git a/templates/webpages/admin/delete_group_confirm.html b/templates/webpages/admin/delete_group_confirm.html
deleted file mode 100644 (file)
index 3b46941..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[%- USE T8 %]
-[%- USE HTML %]
-  <h1>[% 'Delete group' | $T8 %]: [% name %]</h1>
-  <p class="message_hint">[ [% name %] ] - [% 'Do you really want to delete this group?' | $T8 %]</p>
-
-   <form name="Form" method="post" action="admin.pl">
-    <a href="admin.pl?action=edit_groups">[% 'Back' | $T8 %]</a>
-
-    <input type="hidden" name="group_id" value="[% HTML.escape(id) %]">
-    <input type="hidden" name="confirmed" value="1">
-    <input type="hidden" name="delete_nextsub" value="delete_group">
-    <input type="submit" class="submit" name="action" value="[% 'Delete' | $T8 %]">
-   </form>
index 4dcec1a..32a20b0 100644 (file)
-[% USE T8 %][% USE HTML %][% USE L %][% USE LxERP -%]
- [% L.javascript_tag('jquery.selectboxes', 'jquery.multiselect2side') %]
+[%- USE HTML %]
+[%- USE L %][%- USE LxERP -%]
 
-<h1>[% 'Edit group ' | $T8 %]:  [% HTML.escape(name) %]</h1>
+[%- INCLUDE 'common/flash.html' %]
 
- <form name="Form" method="post" action="admin.pl">
-  [% IF message %]
-  <p class="message_ok">[% message %]</p>
-  [% END %]
+<h1>[% HTML.escape(title) %]</h1>
 
-  <p><a href="admin.pl?action=edit_groups">[% 'Back' | $T8 %]</a></p>
+<p>[% L.link(SELF.url_for(action="show"), LxERP.t8("Back")) %]</p>
 
-   <hr>
+<form method="post" action="controller.pl" id="form">
+ [% L.hidden_tag("group.id", SELF.group.id) %]
+ [% L.hidden_tag("action", "") %]
 
-  <h3 class="listheading">[%- LxERP.t8('Edit membership') %]</h3>
+ <h2>[%- LxERP.t8("Settings") %]</h2>
+
+ <table>
+  <tr>
+   <th align="right">[% LxERP.t8('Name') %]</th>
+   <td>[% L.input_tag("group.name", SELF.group.name) %]</td>
+  </tr>
+
+  <tr>
+   <th align="right">[% LxERP.t8('Description') %]</th>
+   <td>[% L.input_tag("group.description", SELF.group.description) %]</td>
+  </tr>
+ </table>
+
+ <h2>[% LxERP.t8("Access rights") %]</h2>
+
+ [% SET granted_rights = SELF.group.rights_map %]
+
+ [%- FOREACH section = SELF.all_rights %]
+  [% SET section_number = loop.count %]
+  [% SET num_checked = 0 %]
+  [% FOREACH right = section.rights %][% SET name = right.name %][% IF granted_rights.$name %][% SET num_checked = num_checked + 1 %][% END %][% END %]
+  <h3>[% L.checkbox_tag('dummy' _ section_number, label=LxERP.t8('Section "#1"', section.description), checkall='[data-checkallgroup=' _ section_number _ ']', checked=(num_checked == section.rights.size)) %]</h3>
 
   <div class="clearfix">
-   [% L.select_tag('user_ids[]', ALL_USERS, id='user_ids', value_key = 'id', title_key = 'login', default = USER_IDS_IN_GROUP, multiple = 1) %]
+   [% FOREACH right = section.rights %]
+    [% SET name = right.name %]
+    [% L.checkbox_tag("group.rights_map." _ name, label=right.description, checked=granted_rights.$name, 'data-checkallgroup'=section_number) %]
+    <br>
+   [%- END %]
   </div>
+ [%- END %]
+
+ <h2>[%- LxERP.t8("Group membership") %]</h2>
+
+[% IF SELF.all_users.size %]
+ <p>
+  [%- LxERP.t8("The following users are a member of this group") %]:
+ </p>
+
+ <div class="clearfix">
+  [% L.select_tag("group.users[]", SELF.all_users, id="group_users", title_key="login", default=SELF.group.users, default_key='id', multiple=1) %]
+  [% L.multiselect2side("group_users", labelsx => LxERP.t8("All users"), labeldx => LxERP.t8("Users that are a member in this group")) %]
+ </div>
+
+[%- ELSE %]
+ <p>
+  [% LxERP.t8("No users have been created yet.") %]
+ </p>
+[%- END %]
+
+ <h2>[%- LxERP.t8("Group assignment") %]</h2>
+
+[% IF SELF.all_clients.size %]
+ <p>
+  [%- LxERP.t8("This group is valid for the following clients") %]:
+ </p>
+
+ <div class="clearfix">
+  [% L.select_tag("group.clients[]", SELF.all_clients, id="group_clients", title_key="name", default=SELF.group.clients, default_key='id', multiple=1) %]
+  [% L.multiselect2side("group_clients", labelsx => LxERP.t8("All clients"), labeldx => LxERP.t8("Clients this Group is valid for")) %]
+ </div>
+
+[%- ELSE %]
+ <p>
+  [% LxERP.t8("No clients have been created yet.") %]
+ </p>
+[%- END %]
+
+<hr size="3" noshade>
+
+<p>
+ [% L.link(SELF.url_for(action="show"), LxERP.t8("Back")) %]
+
+ [% L.button_tag("submit_with_action('save_group')", LxERP.t8("Save")) %]
+ [% IF SELF.group.id %]
+  [% L.button_tag("save_as_new()", LxERP.t8("Save as new")) %]
+  [% L.button_tag("submit_with_action('delete_group')", LxERP.t8("Delete"), confirm=LxERP.t8("Are you sure?")) %]
+ [%- END %]
+</p>
+
+</form>
+
+<script type="text/javascript">
+ <!--
+  function submit_with_action(action) {
+    $("#action").val("Admin/" + action);
+    $("#form").submit();
+  }
+
+  function save_as_new() {
+    var new_group_name = prompt("[% LxERP.t8("Please enter the name for the new group.") %]", "");
+    if (!new_group_name)
+      return;
 
-  <h3 class="listheading">[% 'Edit rights' | $T8 %]</h3>
-
-  <p>
-   [% FOREACH right = RIGHTS %]
-    [% IF right.is_section %]
-     <i>[% right.description %]</i><br>
-    [% ELSE %]
-     <input type="checkbox" name="[% HTML.escape(right.right) %]_granted" id="[% HTML.escape(right.right) %]_granted" [% IF right.granted %]checked[% END %]>
-     <label for="[% HTML.escape(right.right) %]_granted">[% IF right.description %][% right.description %][% ELSE %]<i>[% HTML.escape(right.right) %]</i>[% END %]</label>
-     <br>
-    [% END %]
-   [% END %]
-  </p>
-
-  <h3 class="listheading">[% LxERP.t8('Rename the group') %]</h3>
-
-  <table>
-   <tr>
-    <td>[% 'Name' | $T8 %]:</td>
-    <td><input name="name" maxlength="50" value="[% HTML.escape(name) %]"></td>
-   </tr>
-
-   <tr>
-    <td>[% 'Description' | $T8 %]:</td>
-    <td><input name="description" value="[% HTML.escape(description) %]"></td>
-   </tr>
-  </table>
-
-  <p>
-   <input type="hidden" name="group_id" value="[% HTML.escape(group_id) %]">
-   <input type="hidden" name="action" value="save_group">
-   <input type="submit" class="submit" value="[% 'Save' | $T8 %]">
-   &nbsp;
-   <a href="admin.pl?action=edit_groups">[% 'Back' | $T8 %]</a>
-  </p>
- </form>
-
- [% L.multiselect2side('user_ids', labelsx => LxERP.t8('All users'), labeldx => LxERP.t8('Users in this group')) %]
+    $("#group_name").val(new_group_name);
+    $("#group_id").val("");
+    submit_with_action("save_group");
+  }
+   -->
+</script>
diff --git a/templates/webpages/admin/edit_group_membership.html b/templates/webpages/admin/edit_group_membership.html
deleted file mode 100644 (file)
index be0a46d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-[%- USE T8 %]
-[%- USE HTML %][%- USE LxERP %]
-
- <h1>[% 'Edit group membership' | $T8 %]</h1>
-
- <p><a href="admin.pl?action=edit_groups">[% 'Back' | $T8 %]</a></p>
- <p>[% 'Select the checkboxes that match users to the groups they should belong to.' | $T8 %]</p>
-
- <form action="admin.pl">
-
-  <p>
-   <table border="0">
-    [% FOREACH user = USERS %]
-
-    [% IF user.repeat_headings %]
-    <tr>
-     <th class="listheading" valign="bottom">[% 'Login Name' | $T8 %]</th>
-     <th class="listheading" valign="bottom">[% 'Name' | $T8 %]</th>
-     [% FOREACH column = HEADINGS %]<th class="listheading" valign="bottom" align="center">[% LxERP.turn90(column.title) %]</th>
-     [% END %]
-    </tr>
-    [% END %]
-
-    <tr class="listrow[% loop.count % 2 %]">
-     <td valign="center">[% HTML.escape(user.login) %]</td>
-     <td valign="center">[% HTML.escape(user.name) %]</td>
-     [% FOREACH group = user.GROUPS %]
-     <td valign="center" align="center">
-      <input type="checkbox" name="u_[% HTML.escape(user.id) %]_g_[% HTML.escape(group.id) %]" [% IF group.is_member %]checked[% END %]>
-     </td>
-     [% END %]
-    </tr>
-    [% END %]
-   </table>
-  </p>
-
-  <input type="hidden" name="save_nextsub" value="save_group_membership">
-  <input type="hidden" name="back_nextsub" value="edit_groups">
-
-  <p>
-   <input type="submit" class="submit" name="action" value="[% 'Save' | $T8 %]">
-  </p>
-
- </form>
diff --git a/templates/webpages/admin/edit_groups.html b/templates/webpages/admin/edit_groups.html
deleted file mode 100644 (file)
index b17539d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-[%- USE T8 %]
-[%- USE HTML %]
-
-  <h1>[% 'Edit groups' | $T8 %]</h1>
-  [% IF message %]
-  <p class="message_ok">[% message %]</p>
-  [% END %]
-
-  <p><a href="admin.pl?action=login">[% 'Back' | $T8 %]</a></p>
-
- <h2>[% 'Add a new group' | $T8 %]</h2>
-
- <form method="post" action="admin.pl">
- <br>
-  <table border="0">
-   <tr><td>[% 'Name' | $T8 %] </td><td><input name="name" maxlength="50"></td></tr>
-   <tr><td>[% 'Description' | $T8 %] </td><td><input name="description"></td></tr>
-  </table>
-   <input type="hidden" name="add_nextsub" value="add_group">
-   <p><input type="submit" class="submit" name="action" value="[% 'Add' | $T8 %]"></p>
- </form>
-
- <h2>[% 'Edit and delete a group' | $T8 %]</h2>
-
- <form name="Form" method="post" action="admin.pl">
-  [% IF num_groups %]
-  <p>
-   <select name="group_id" size="10">
-    [% FOREACH row = GROUPS %]
-    <option value="[% HTML.escape(row.id) %]"[% ' selected' IF loop.first %]>[% HTML.escape(row.name) %][% IF row.description %] ([% HTML.escape(row.description) %])[% END %]</option>
-    [% END %]
-   </select>
-  </p>
-  [% ELSE %]
-  <p>[% 'No groups have been added yet.' | $T8 %]</p>
-  [% END %]
-
-  <p>
-   [% IF num_groups %]
-   <input type="hidden" name="edit_nextsub" value="edit_group">
-   <input type="hidden" name="delete_nextsub" value="delete_group">
-   <input type="submit" class="submit" name="action" value="[% 'Edit' | $T8 %]">
-   <input type="submit" class="submit" name="action" value="[% 'Delete' | $T8 %]">
-   [% END %]
-  </p>
- </form>
-
- <h2>[% 'Group membership' | $T8 %]</h2>
-
- <p>[% 'Edit the membership of all users in all groups:' | $T8 %]</p>
-
- <form method="post" action="admin.pl">
-  <p>
-   <input type="hidden" name="edit_nextsub" value="edit_group_membership">
-   <input type="submit" class="submit" name="action" value="[% 'Edit' | $T8 %]">
-  </p>
-
- </form>
-
- <hr size="2" noshade>
index 1fb9eff..dc7b9d7 100644 (file)
@@ -3,7 +3,7 @@
 
 [%- INCLUDE 'common/flash.html' %]
 
-<h1>[% title %]</h1>
+<h1>[% HTML.escape(title) %]</h1>
 
 <p>[% L.link(SELF.url_for(action="show"), LxERP.t8("Back")) %]</p>
 
index 1f1a834..734deae 100644 (file)
  <span class="link_separator">|</span>
  [% L.link(SELF.url_for(action="new_client"), LxERP.t8("Add Client")) %]
  <span class="link_separator">|</span>
- [% L.link(SELF.url_for(action="edit_groups"), LxERP.t8("Edit groups")) %]
+ [% L.link(SELF.url_for(action="new_group"), LxERP.t8("Add User Group")) %]
  <span class="link_separator">|</span>
  [% L.link(SELF.url_for(action="pg_database_administration", controller="admin.pl"), LxERP.t8("Pg Database Administration")) %]
  <span class="link_separator">|</span>
  [% L.link(SELF.url_for(action="printer_management", controller="admin.pl"), LxERP.t8("Printer Management")) %]
  <span class="link_separator">|</span>
- [% IF LOCKED %]
+ [% IF SELF.is_locked %]
   [% L.link(SELF.url_for(action="unlock_system"), LxERP.t8("Unlock System")) %]
  [% ELSE %]
   [% L.link(SELF.url_for(action="lock_system"), LxERP.t8("Lock System")) %]
  <ul>
   <li><a href="#user_list">[%- LxERP.t8("User list") %]</a></li>
   <li><a href="#client_list">[%- LxERP.t8("Client list") %]</a></li>
+  <li><a href="#group_list">[%- LxERP.t8("Group list") %]</a></li>
  </ul>
 
  <div id="user_list">
-[%- IF !USERS.size %]
+[%- IF !SELF.all_users.size %]
   <p>
    [% LxERP.t8("No users have been created yet.") %]
-   [% LxERP.t8("In order to use kivitendo you have to create at least one client, one user, and grant that user access to the client.") %]
+   [% LxERP.t8("In order to use kivitendo you have to create at least a client, a user and a group.") %]
   </p>
 
 [%- ELSE %]
@@ -51,7 +52,7 @@
     <th>[% LxERP.t8('Language') %]</th>
    </tr>
 
-[% FOREACH user = USERS %]
+[% FOREACH user = SELF.all_users %]
 [%- SET config = user.config_values %]
    <tr class="listrow">
     <td>[% L.link(SELF.url_for(action="edit_user", id=user.id), HTML.escape(user.login)) %]</td>
  </div>
 
  <div id="client_list">
-[%- IF !CLIENTS.size %]
+[%- IF !SELF.all_clients.size %]
   <p>
    [% LxERP.t8("No clients have been created yet.") %]
-   [% LxERP.t8("In order to use kivitendo you have to create at least one client, one user, and grant that user access to the client.") %]
+   [% LxERP.t8("In order to use kivitendo you have to create at least a client, a user and a group.") %]
   </p>
 
 [%- ELSE %]
@@ -81,7 +82,7 @@
     <th>[% LxERP.t8('Default client') %]</th>
    </tr>
 
-[%- FOREACH client = CLIENTS %]
+[%- FOREACH client = SELF.all_clients %]
    <tr class="listrow">
     <td>[% L.link(SELF.url_for(action="edit_client", id=client.id), HTML.escape(client.name)) %]</td>
     <td>[% HTML.escape(client.id) %]</td>
    </tr>
 [%- END %]
   </table>
+[%- END %]
+ </div>
+
+ <div id="group_list">
+[%- IF !SELF.all_groups.size %]
+  <p>
+   [% LxERP.t8("No groups have been created yet.") %]
+   [% LxERP.t8("In order to use kivitendo you have to create at least a client, a user and a group.") %]
+  </p>
+
+[%- ELSE %]
+  <table width="100%">
+   <tr class="listheading">
+    <th>[% LxERP.t8('Name') %]</th>
+    <th>[% LxERP.t8('Description') %]</th>
+   </tr>
+
+[%- FOREACH group = SELF.all_groups %]
+   <tr class="listrow">
+    <td>[% L.link(SELF.url_for(action="edit_group", id=group.id), HTML.escape(group.name)) %]</td>
+    <td>[% HTML.escape(group.description) %]</td>
+   </tr>
+[%- END %]
+  </table>
 [%- END %]
  </div>
 </div>