commit 459574b971b01d2cc88c5d4cbe1ad14c11b19ec7
Author: Moritz Bunkus <m.bunkus@linet.de>
Date:   Wed Feb 1 15:49:20 2017 +0100

    SimpleSystemSetting: Umstellung von »Pflichtenhefte« → »Komplexitätsgrade«, »Risikograde«

diff --git a/SL/Controller/RequirementSpecComplexity.pm b/SL/Controller/RequirementSpecComplexity.pm
deleted file mode 100644
index 392a3c399..000000000
--- a/SL/Controller/RequirementSpecComplexity.pm
+++ /dev/null
@@ -1,114 +0,0 @@
-package SL::Controller::RequirementSpecComplexity;
-
-use strict;
-
-use parent qw(SL::Controller::Base);
-
-use SL::DB::RequirementSpecComplexity;
-use SL::Helper::Flash;
-use SL::Locale::String;
-
-use Rose::Object::MakeMethods::Generic
-(
- scalar => [ qw(requirement_spec_complexity) ],
-);
-
-__PACKAGE__->run_before('check_auth');
-__PACKAGE__->run_before('load_requirement_spec_complexity', only => [ qw(edit update destroy) ]);
-
-#
-# actions
-#
-
-sub action_list {
-  my ($self) = @_;
-
-  $self->render('requirement_spec_complexity/list',
-                title                         => t8('Complexities'),
-                REQUIREMENT_SPEC_COMPLEXITIES => SL::DB::Manager::RequirementSpecComplexity->get_all_sorted);
-}
-
-sub action_new {
-  my ($self) = @_;
-
-  $self->{requirement_spec_complexity} = SL::DB::RequirementSpecComplexity->new;
-  $self->render('requirement_spec_complexity/form', title => t8('Create a new complexity'));
-}
-
-sub action_edit {
-  my ($self) = @_;
-  $self->render('requirement_spec_complexity/form', title => t8('Edit complexity'));
-}
-
-sub action_create {
-  my ($self) = @_;
-
-  $self->{requirement_spec_complexity} = SL::DB::RequirementSpecComplexity->new;
-  $self->create_or_update;
-}
-
-sub action_update {
-  my ($self) = @_;
-  $self->create_or_update;
-}
-
-sub action_destroy {
-  my ($self) = @_;
-
-  if (eval { $self->{requirement_spec_complexity}->delete; 1; }) {
-    flash_later('info',  t8('The complexity has been deleted.'));
-  } else {
-    flash_later('error', t8('The complexity is in use and cannot be deleted.'));
-  }
-
-  $self->redirect_to(action => 'list');
-}
-
-sub action_reorder {
-  my ($self) = @_;
-
-  SL::DB::RequirementSpecComplexity->reorder_list(@{ $::form->{requirement_spec_complexity_id} || [] });
-
-  $self->render(\'', { type => 'json' });
-}
-
-#
-# filters
-#
-
-sub check_auth {
-  $::auth->assert('config');
-}
-
-#
-# helpers
-#
-
-sub create_or_update {
-  my $self   = shift;
-  my $is_new = !$self->{requirement_spec_complexity}->id;
-  my $params = delete($::form->{requirement_spec_complexity}) || { };
-  my $title  = $is_new ? t8('Create a new complexity') : t8('Edit complexity');
-
-  $self->{requirement_spec_complexity}->assign_attributes(%{ $params });
-
-  my @errors = $self->{requirement_spec_complexity}->validate;
-
-  if (@errors) {
-    flash('error', @errors);
-    $self->render('requirement_spec_complexity/form', title => $title);
-    return;
-  }
-
-  $self->{requirement_spec_complexity}->save;
-
-  flash_later('info', $is_new ? t8('The complexity has been created.') : t8('The complexity has been saved.'));
-  $self->redirect_to(action => 'list');
-}
-
-sub load_requirement_spec_complexity {
-  my ($self) = @_;
-  $self->{requirement_spec_complexity} = SL::DB::RequirementSpecComplexity->new(id => $::form->{id})->load;
-}
-
-1;
diff --git a/SL/Controller/RequirementSpecRisk.pm b/SL/Controller/RequirementSpecRisk.pm
deleted file mode 100644
index bfa7aaddc..000000000
--- a/SL/Controller/RequirementSpecRisk.pm
+++ /dev/null
@@ -1,114 +0,0 @@
-package SL::Controller::RequirementSpecRisk;
-
-use strict;
-
-use parent qw(SL::Controller::Base);
-
-use SL::DB::RequirementSpecRisk;
-use SL::Helper::Flash;
-use SL::Locale::String;
-
-use Rose::Object::MakeMethods::Generic
-(
- scalar => [ qw(requirement_spec_risk) ],
-);
-
-__PACKAGE__->run_before('check_auth');
-__PACKAGE__->run_before('load_requirement_spec_risk', only => [ qw(edit update destroy) ]);
-
-#
-# actions
-#
-
-sub action_list {
-  my ($self) = @_;
-
-  $self->render('requirement_spec_risk/list',
-                title                  => t8('Risk levels'),
-                REQUIREMENT_SPEC_RISKS => SL::DB::Manager::RequirementSpecRisk->get_all_sorted);
-}
-
-sub action_new {
-  my ($self) = @_;
-
-  $self->{requirement_spec_risk} = SL::DB::RequirementSpecRisk->new;
-  $self->render('requirement_spec_risk/form', title => t8('Create a new risk level'));
-}
-
-sub action_edit {
-  my ($self) = @_;
-  $self->render('requirement_spec_risk/form', title => t8('Edit risk level'));
-}
-
-sub action_create {
-  my ($self) = @_;
-
-  $self->{requirement_spec_risk} = SL::DB::RequirementSpecRisk->new;
-  $self->create_or_update;
-}
-
-sub action_update {
-  my ($self) = @_;
-  $self->create_or_update;
-}
-
-sub action_destroy {
-  my ($self) = @_;
-
-  if (eval { $self->{requirement_spec_risk}->delete; 1; }) {
-    flash_later('info',  t8('The risk level has been deleted.'));
-  } else {
-    flash_later('error', t8('The risk level is in use and cannot be deleted.'));
-  }
-
-  $self->redirect_to(action => 'list');
-}
-
-sub action_reorder {
-  my ($self) = @_;
-
-  SL::DB::RequirementSpecRisk->reorder_list(@{ $::form->{requirement_spec_risk_id} || [] });
-
-  $self->render(\'', { type => 'json' });
-}
-
-#
-# filters
-#
-
-sub check_auth {
-  $::auth->assert('config');
-}
-
-#
-# helpers
-#
-
-sub create_or_update {
-  my $self   = shift;
-  my $is_new = !$self->{requirement_spec_risk}->id;
-  my $params = delete($::form->{requirement_spec_risk}) || { };
-  my $title  = $is_new ? t8('Create a new risk level') : t8('Edit risk level');
-
-  $self->{requirement_spec_risk}->assign_attributes(%{ $params });
-
-  my @errors = $self->{requirement_spec_risk}->validate;
-
-  if (@errors) {
-    flash('error', @errors);
-    $self->render('requirement_spec_risk/form', title => $title);
-    return;
-  }
-
-  $self->{requirement_spec_risk}->save;
-
-  flash_later('info', $is_new ? t8('The risk level has been created.') : t8('The risk level has been saved.'));
-  $self->redirect_to(action => 'list');
-}
-
-sub load_requirement_spec_risk {
-  my ($self) = @_;
-  $self->{requirement_spec_risk} = SL::DB::RequirementSpecRisk->new(id => $::form->{id})->load;
-}
-
-1;
diff --git a/SL/Controller/SimpleSystemSetting.pm b/SL/Controller/SimpleSystemSetting.pm
index 5660f22c2..de0feb073 100644
--- a/SL/Controller/SimpleSystemSetting.pm
+++ b/SL/Controller/SimpleSystemSetting.pm
@@ -155,6 +155,15 @@ my %supported_types = (
     ],
   },
 
+  requirement_spec_complexity => {
+    class  => 'RequirementSpecComplexity',
+    titles => {
+      list => t8('Complexities'),
+      add  => t8('Add complexity'),
+      edit => t8('Edit complexity'),
+    },
+  },
+
   requirement_spec_predefined_text => {
     # Make locales.pl happy: $self->render("simple_system_setting/_requirement_spec_predefined_text_form")
     class  => 'RequirementSpecPredefinedText',
@@ -172,6 +181,15 @@ my %supported_types = (
     ],
   },
 
+  requirement_spec_risk => {
+    class  => 'RequirementSpecRisk',
+    titles => {
+      list => t8('Risk levels'),
+      add  => t8('Add risk level'),
+      edit => t8('Edit risk level'),
+    },
+  },
+
   requirement_spec_status => {
     # Make locales.pl happy: $self->render("simple_system_setting/_requirement_spec_status_form")
     class  => 'RequirementSpecStatus',
diff --git a/locale/de/all b/locale/de/all
index 8b40876e2..94ea31fd8 100755
--- a/locale/de/all
+++ b/locale/de/all
@@ -192,6 +192,7 @@ $self->{texts} = {
   'Add bank account'            => 'Bankkonto erfassen',
   'Add booking group'           => 'Buchungsgruppe erfassen',
   'Add business'                => 'Kunden-/Lieferantentyp hinzufügen',
+  'Add complexity'              => 'Komplexitätsgrad hinzufügen',
   'Add custom variable'         => 'Benutzerdefinierte Variable erfassen',
   'Add department'              => 'Abteilung hinzufügen',
   'Add empty line (csv_import)' => 'Leere Zeile einfügen',
@@ -218,6 +219,7 @@ $self->{texts} = {
   'Add project type'            => 'Projekttypen hinzufügen',
   'Add requirement spec status' => 'Pflichtenheftstatus hinzufügen',
   'Add requirement spec type'   => 'Pflichtenhefttypen hinzufügen',
+  'Add risk level'              => 'Risikograd hinzufügen',
   'Add section'                 => 'Abschnitt hinzufügen',
   'Add sub function block'      => 'Unterfunktionsblock hinzufügen',
   'Add taxzone'                 => 'Steuerzone hinzufügen',
@@ -667,7 +669,6 @@ $self->{texts} = {
   'Create PDF'                  => 'PDF erzeugen',
   'Create a new background job' => 'Einen neuen Hintergrund-Job anlegen',
   'Create a new client'         => 'Einen neuen Mandanten anlegen',
-  'Create a new complexity'     => 'Einen Komplexitätsgrad anlegen',
   'Create a new delivery term'  => 'Neue Lieferbedingungen anlegen',
   'Create a new group'          => 'Neue Benutzergruppe erfassen',
   'Create a new payment term'   => 'Neue Zahlungsbedingungen anlegen',
@@ -678,7 +679,6 @@ $self->{texts} = {
   'Create a new purchase price rule' => 'Neue Einkaufspreisregel anlegen',
   'Create a new requirement spec' => 'Ein neues Pflichtenheft anlegen',
   'Create a new requirement spec template' => 'Eine neue Pflichtenheftvorlage erfassen',
-  'Create a new risk level'     => 'Einen neuen Risikograd anlegen',
   'Create a new sales price rule' => 'Neue Verkaufspreisregel anlegen',
   'Create a new user'           => 'Einen neuen Benutzer anlegen',
   'Create a new user group'     => 'Eine neue Benutzergruppe erfassen',
@@ -1850,7 +1850,6 @@ $self->{texts} = {
   'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerpl&auml;tze angelegt.',
   'No changes since previous version.' => 'Keine Änderungen seit der letzten Version.',
   'No clients have been created yet.' => 'Es wurden noch keine Mandanten angelegt.',
-  'No complexities has been created yet.' => 'Es wurden noch keine Komplexitätsgrade angelegt.',
   'No contact selected to delete' => 'Keine Ansprechperson zum Löschen ausgewählt',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No data was found.'          => 'Es wurden keine Daten gefunden.',
@@ -1887,7 +1886,6 @@ $self->{texts} = {
   'No requirement spec templates have been created yet.' => 'Es wurden noch keine Pflichtenheftvorlagen angelegt.',
   'No results.'                 => 'Keine Artikel',
   'No revert available.'        => 'Dieser Vorgang kann nicht rückgängig gemacht werden, ggf. falsch erstellte Buchungen müssen einzeln manuell korrigiert werden.',
-  'No risks level has been created yet.' => 'Es wurden noch keine Risikograde angelegt.',
   'No search results found!'    => 'Keine Suchergebnisse gefunden!',
   'No sections created yet'     => 'Keine Abschnitte erstellt',
   'No sections have been created so far.' => 'Bisher wurden noch keine Abschnitte angelegt.',
@@ -2925,10 +2923,6 @@ $self->{texts} = {
   '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.' => 'Die Kombination aus Datenbankhost, -port und -name ist nicht eindeutig.',
   'The command is missing.'     => 'Der Befehl fehlt.',
-  'The complexity has been created.' => 'Der Komplexitätsgrad wurde angelegt.',
-  'The complexity has been deleted.' => 'Der Komplexitätsgrad wurde gelöscht.',
-  'The complexity has been saved.' => 'Der Komplexitätsgrad wurde gespeichert.',
-  'The complexity is in use and cannot be deleted.' => 'Der Komplexitätsgrad wird verwendet und kann nicht gelöscht werden.',
   '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.',
@@ -3083,10 +3077,6 @@ $self->{texts} = {
   'The requirement spec has been saved.' => 'Das Pflichtenheft wurde gespeichert.',
   'The requirement spec is in use and cannot be deleted.' => 'Das Pflichtenheft wird verwendet und kann nicht gelöscht werden.',
   'The requirement spec template has been saved.' => 'Die Pflichtenheftvorlage wurde gespeichert.',
-  'The risk level has been created.' => 'Der Risikograd wurde angelegt.',
-  'The risk level has been deleted.' => 'Der Risikograd wurde gelöscht.',
-  'The risk level has been saved.' => 'Der Risikograd wurde gespeichert.',
-  'The risk level is in use and cannot be deleted.' => 'Der Risikograd wird verwendet und kann nicht gelöscht werden.',
   'The second reason is that kivitendo allowed the user to enter the tax amount manually regardless of the taxkey used.' => 'Der zweite Grund war, dass kivitendo zuließ, dass die Benutzer beliebige, von den tatsächlichen Steuerschlüsseln unabhängige Steuerbeträge eintrugen.',
   'The second way is to use Perl\'s CPAN module and let it download and install the module for you.' => 'Die zweite Variante besteht darin, Perls CPAN-Modul zu benutzen und es das Modul f&uuml;r Sie installieren zu lassen.',
   'The selected bank account does not exist anymore.' => 'Das ausgewählte Bankkonto existiert nicht mehr.',
diff --git a/menus/user/00-erp.yaml b/menus/user/00-erp.yaml
index 79522ba5b..77ca36ea4 100644
--- a/menus/user/00-erp.yaml
+++ b/menus/user/00-erp.yaml
@@ -1161,13 +1161,15 @@
   name: Complexities
   order: 400
   params:
-    action: RequirementSpecComplexity/list
+    action: SimpleSystemSetting/list
+    type: requirement_spec_complexity
 - parent: system_requirement_specs
   id: system_requirement_specs_risks
   name: Risks
   order: 500
   params:
-    action: RequirementSpecRisk/list
+    action: SimpleSystemSetting/list
+    type: requirement_spec_risk
 - parent: system_requirement_specs
   id: system_requirement_specs_acceptance_statuses
   name: Acceptance Statuses
diff --git a/templates/webpages/requirement_spec_complexity/form.html b/templates/webpages/requirement_spec_complexity/form.html
deleted file mode 100755
index 8088db5e7..000000000
--- a/templates/webpages/requirement_spec_complexity/form.html
+++ /dev/null
@@ -1,24 +0,0 @@
-[% USE HTML %][% USE L %][% USE LxERP %]
-<h1>[% FORM.title %]</h1>
-
- <form method="post" action="controller.pl">
-
-[%- INCLUDE 'common/flash.html' %]
-
-  <table>
-   <tr>
-    <td>[% LxERP.t8("Description") %]</td>
-    <td>[% L.input_tag("requirement_spec_complexity.description", SELF.requirement_spec_complexity.description) %]</td>
-   </tr>
-  </table>
-
-  <p>
-   [% L.hidden_tag("id", SELF.requirement_spec_complexity.id) %]
-   [% L.hidden_tag("action", "RequirementSpecComplexity/dispatch") %]
-   [% L.submit_tag("action_" _ (SELF.requirement_spec_complexity.id ? "update" : "create"), LxERP.t8('Save')) %]
-   [%- IF SELF.requirement_spec_complexity.id %]
-    [% L.submit_tag("action_destroy", LxERP.t8('Delete'), confirm=LxERP.t8('Do you really want to delete this object?')) %]
-   [%- END %]
-   <a href="[% SELF.url_for(action => 'list') %]">[%- LxERP.t8('Abort') %]</a>
-  </p>
- </form>
diff --git a/templates/webpages/requirement_spec_complexity/list.html b/templates/webpages/requirement_spec_complexity/list.html
deleted file mode 100644
index 0f962b490..000000000
--- a/templates/webpages/requirement_spec_complexity/list.html
+++ /dev/null
@@ -1,41 +0,0 @@
-[% USE HTML %][% USE L %][% USE LxERP %]
-<h1>[% FORM.title %]</h1>
-
-[%- INCLUDE "common/flash.html" %]
-
- <form method="post" action="controller.pl">
-  [% IF !REQUIREMENT_SPEC_COMPLEXITIES.size %]
-   <p>
-    [%- LxERP.t8("No complexities has been created yet.") %]
-   </p>
-
-  [%- ELSE %]
-   <table id="requirement_spec_complexity_list">
-    <thead>
-    <tr class="listheading">
-     <th align="center"><img src="image/updown.png" alt="[%- LxERP.t8("reorder item") %]"></th>
-     <th>[%- LxERP.t8("Description") %]</th>
-    </tr>
-    </thead>
-
-    <tbody>
-    [%- FOREACH requirement_spec_complexity = REQUIREMENT_SPEC_COMPLEXITIES %]
-    <tr class="listrow[% loop.count % 2 %]" id="requirement_spec_complexity_id_[% requirement_spec_complexity.id %]">
-     <td align="center" class="dragdrop"><img src="image/updown.png" alt="[%- LxERP.t8("reorder item") %]"></td>
-     <td>
-      <a href="[% SELF.url_for(action => "edit", id => requirement_spec_complexity.id) %]">
-       [%- HTML.escape(requirement_spec_complexity.description) %]
-      </a>
-     </td>
-    </tr>
-    [%- END %]
-    </tbody>
-   </table>
-  [%- END %]
-
-  <p>
-   <a href="[% SELF.url_for(action => "new") %]">[%- LxERP.t8("Create a new complexity") %]</a>
-  </p>
- </form>
-
- [% L.sortable_element("#requirement_spec_complexity_list tbody", url => "controller.pl?action=RequirementSpecComplexity/reorder", with => "requirement_spec_complexity_id") %]
diff --git a/templates/webpages/requirement_spec_risk/form.html b/templates/webpages/requirement_spec_risk/form.html
deleted file mode 100755
index 5f4450283..000000000
--- a/templates/webpages/requirement_spec_risk/form.html
+++ /dev/null
@@ -1,24 +0,0 @@
-[% USE HTML %][% USE L %][% USE LxERP %]
-<h1>[% FORM.title %]</h1>
-
- <form method="post" action="controller.pl">
-
-[%- INCLUDE 'common/flash.html' %]
-
-  <table>
-   <tr>
-    <td>[% LxERP.t8("Description") %]</td>
-    <td>[% L.input_tag("requirement_spec_risk.description", SELF.requirement_spec_risk.description) %]</td>
-   </tr>
-  </table>
-
-  <p>
-   [% L.hidden_tag("id", SELF.requirement_spec_risk.id) %]
-   [% L.hidden_tag("action", "RequirementSpecRisk/dispatch") %]
-   [% L.submit_tag("action_" _ (SELF.requirement_spec_risk.id ? "update" : "create"), LxERP.t8('Save')) %]
-   [%- IF SELF.requirement_spec_risk.id %]
-    [% L.submit_tag("action_destroy", LxERP.t8('Delete'), confirm=LxERP.t8('Do you really want to delete this object?')) %]
-   [%- END %]
-   <a href="[% SELF.url_for(action => 'list') %]">[%- LxERP.t8('Abort') %]</a>
-  </p>
- </form>
diff --git a/templates/webpages/requirement_spec_risk/list.html b/templates/webpages/requirement_spec_risk/list.html
deleted file mode 100644
index cca09b99b..000000000
--- a/templates/webpages/requirement_spec_risk/list.html
+++ /dev/null
@@ -1,41 +0,0 @@
-[% USE HTML %][% USE L %][% USE LxERP %]
-<h1>[% FORM.title %]</h1>
-
-[%- INCLUDE "common/flash.html" %]
-
- <form method="post" action="controller.pl">
-  [% IF !REQUIREMENT_SPEC_RISKS.size %]
-   <p>
-    [%- LxERP.t8("No risks level has been created yet.") %]
-   </p>
-
-  [%- ELSE %]
-   <table id="requirement_spec_risk_list">
-    <thead>
-    <tr class="listheading">
-     <th align="center"><img src="image/updown.png" alt="[%- LxERP.t8("reorder item") %]"></th>
-     <th>[%- LxERP.t8("Description") %]</th>
-    </tr>
-    </thead>
-
-    <tbody>
-    [%- FOREACH requirement_spec_risk = REQUIREMENT_SPEC_RISKS %]
-    <tr class="listrow[% loop.count % 2 %]" id="requirement_spec_risk_id_[% requirement_spec_risk.id %]">
-     <td align="center" class="dragdrop"><img src="image/updown.png" alt="[%- LxERP.t8("reorder item") %]"></td>
-     <td>
-      <a href="[% SELF.url_for(action => "edit", id => requirement_spec_risk.id) %]">
-       [%- HTML.escape(requirement_spec_risk.description) %]
-      </a>
-     </td>
-    </tr>
-    [%- END %]
-    </tbody>
-   </table>
-  [%- END %]
-
-  <p>
-   <a href="[% SELF.url_for(action => "new") %]">[%- LxERP.t8("Create a new risk level") %]</a>
-  </p>
- </form>
-
- [% L.sortable_element("#requirement_spec_risk_list tbody", url => "controller.pl?action=RequirementSpecRisk/reorder", with => "requirement_spec_risk_id") %]
