commit 5efe13905a6ef7dbd22650cc9c1c17a246277484
Author: Bernd Bleßmann <bernd@kivitendo-premium.de>
Date:   Mon Sep 20 14:31:51 2021 +0200

    Auftrags-Controller: Warnung bei nicht vorhandener Kundenbestellummer …
    
    … kann in der Mandantenkonfiguration eingeschaltet werden.

diff --git a/SL/Controller/Order.pm b/SL/Controller/Order.pm
index 284e200ab..fdfa155c8 100644
--- a/SL/Controller/Order.pm
+++ b/SL/Controller/Order.pm
@@ -1893,6 +1893,7 @@ sub setup_edit_action_bar {
                       || (($self->type eq purchase_order_type()) && $::instance_conf->get_purchase_order_show_delete);
 
   my @req_trans_cost_art = qw(kivi.Order.check_transport_cost_article_presence) x!!$::instance_conf->get_transport_cost_reminder_article_number_id;
+  my @req_cusordnumber   = qw(kivi.Order.check_cusordnumber_presence)           x($self->type eq sales_order_type() && $::instance_conf->get_order_warn_no_cusordnumber);
 
   for my $bar ($::request->layout->get('actionbar')) {
     $bar->add(
@@ -1901,13 +1902,17 @@ sub setup_edit_action_bar {
           t8('Save'),
           call      => [ 'kivi.Order.save', 'save', $::instance_conf->get_order_warn_duplicate_parts,
                                                     $::instance_conf->get_order_warn_no_deliverydate,
-                                                                                                      ],
-          checks    => [ 'kivi.Order.check_save_active_periodic_invoices', ['kivi.validate_form','#order_form'], @req_trans_cost_art ],
+          ],
+          checks    => [ 'kivi.Order.check_save_active_periodic_invoices', ['kivi.validate_form','#order_form'],
+                         @req_trans_cost_art, @req_cusordnumber,
+          ],
         ],
         action => [
           t8('Save as new'),
           call      => [ 'kivi.Order.save', 'save_as_new', $::instance_conf->get_order_warn_duplicate_parts ],
-          checks    => [ 'kivi.Order.check_save_active_periodic_invoices', @req_trans_cost_art ],
+          checks    => [ 'kivi.Order.check_save_active_periodic_invoices',
+                         @req_trans_cost_art, @req_cusordnumber,
+          ],
           disabled  => !$self->order->id ? t8('This object has not been saved yet.') : undef,
         ],
       ], # end of combobox "Save"
@@ -1919,7 +1924,7 @@ sub setup_edit_action_bar {
         action => [
           t8('Save and Quotation'),
           submit   => [ '#order_form', { action => "Order/sales_quotation" } ],
-          checks   => [ @req_trans_cost_art ],
+          checks   => [ @req_trans_cost_art, @req_cusordnumber ],
           only_if  => (any { $self->type eq $_ } (sales_order_type())),
         ],
         action => [
@@ -1936,7 +1941,7 @@ sub setup_edit_action_bar {
         action => [
           t8('Save and Purchase Order'),
           call      => [ 'kivi.Order.purchase_order_check_for_direct_delivery' ],
-          checks    => [ @req_trans_cost_art ],
+          checks    => [ @req_trans_cost_art, @req_cusordnumber ],
           only_if   => (any { $self->type eq $_ } (sales_order_type(), request_quotation_type())),
         ],
         action => [
@@ -1944,13 +1949,17 @@ sub setup_edit_action_bar {
           call      => [ 'kivi.Order.save', 'save_and_delivery_order', $::instance_conf->get_order_warn_duplicate_parts,
                                                                        $::instance_conf->get_order_warn_no_deliverydate,
                                                                                                                         ],
-          checks    => [ 'kivi.Order.check_save_active_periodic_invoices', @req_trans_cost_art ],
+          checks    => [ 'kivi.Order.check_save_active_periodic_invoices',
+                         @req_trans_cost_art, @req_cusordnumber,
+          ],
           only_if   => (any { $self->type eq $_ } (sales_order_type(), purchase_order_type()))
         ],
         action => [
           t8('Save and Invoice'),
           call      => [ 'kivi.Order.save', 'save_and_invoice', $::instance_conf->get_order_warn_duplicate_parts ],
-          checks    => [ 'kivi.Order.check_save_active_periodic_invoices', @req_trans_cost_art ],
+          checks    => [ 'kivi.Order.check_save_active_periodic_invoices',
+                         @req_trans_cost_art, @req_cusordnumber,
+          ],
         ],
         action => [
           t8('Save and AP Transaction'),
@@ -1969,14 +1978,14 @@ sub setup_edit_action_bar {
           call   => [ 'kivi.Order.save', 'preview_pdf', $::instance_conf->get_order_warn_duplicate_parts,
                                                         $::instance_conf->get_order_warn_no_deliverydate,
                     ],
-          checks => [ @req_trans_cost_art ],
+          checks => [ @req_trans_cost_art, @req_cusordnumber ],
         ],
         action => [
           t8('Save and print'),
           call   => [ 'kivi.Order.show_print_options', $::instance_conf->get_order_warn_duplicate_parts,
                                                        $::instance_conf->get_order_warn_no_deliverydate,
                     ],
-          checks => [ @req_trans_cost_art ],
+          checks => [ @req_trans_cost_art, @req_cusordnumber ],
         ],
         action => [
           t8('Save and E-mail'),
diff --git a/SL/DB/MetaSetup/Default.pm b/SL/DB/MetaSetup/Default.pm
index b4091917a..4af7d913c 100644
--- a/SL/DB/MetaSetup/Default.pm
+++ b/SL/DB/MetaSetup/Default.pm
@@ -121,6 +121,7 @@ __PACKAGE__->meta->columns(
   normalize_vc_names                        => { type => 'boolean', default => 'true' },
   order_always_project                      => { type => 'boolean', default => 'false' },
   order_warn_duplicate_parts                => { type => 'boolean', default => 'true' },
+  order_warn_no_cusordnumber                => { type => 'boolean', default => 'false' },
   order_warn_no_deliverydate                => { type => 'boolean', default => 'true' },
   parts_image_css                           => { type => 'text', default => 'border:0;float:left;max-width:250px;margin-top:20px:margin-right:10px;margin-left:10px;' },
   parts_listing_image                       => { type => 'boolean', default => 'true' },
diff --git a/doc/changelog b/doc/changelog
index f94a4259b..36616468e 100644
--- a/doc/changelog
+++ b/doc/changelog
@@ -17,11 +17,12 @@ Mittelgroße neue Features:
 
 Kleinere neue Features und Detailverbesserungen:
 
-
 - neue Druckvorlagen-Variante "Rechnungskopie", die mit dem Druckvorlagensatz marei
   ein Wasserzeichen "Rechnungskopie" bei Verkaufs-Rechnungen erzeugt
 - Alle HTML-Textfelder benutzen die Rechtschreibprüfung des Anwender-Browser und
   markieren unbekannte Worte (Tippfehler) mit einer roten gewellten Linie
+- Prüfung, ob Kundenbestellnummer in Verkaufsaufträgen vorhanden ist, kann in der
+  Mandantenkonfiguration eingestellt werden
 
 Bugfixes (Tracker: https://www.kivitendo.de/redmine):
 
@@ -29,7 +30,6 @@ Bugfixes (Tracker: https://www.kivitendo.de/redmine):
 
 
 
-
 2021-08-10 - Release 3.5.8
 
 Kleinere neue Features und Detailverbesserungen:
diff --git a/js/kivi.Order.js b/js/kivi.Order.js
index 140eba2f0..9d2c9e841 100644
--- a/js/kivi.Order.js
+++ b/js/kivi.Order.js
@@ -861,6 +861,13 @@ namespace('kivi.Order', function(ns) {
     return confirm(kivi.t8("The transport cost article '#1' is missing. Do you want to continue anyway?", [ description ]));
   };
 
+  ns.check_cusordnumber_presence = function() {
+    if ($('#order_cusordnumber').val() === '') {
+      return confirm(kivi.t8('The customer order number is missing. Do you want to continue anyway?'));
+    }
+    return true;
+  };
+
 });
 
 $(function() {
diff --git a/js/locale/de.js b/js/locale/de.js
index e36f8829e..3e79c9780 100644
--- a/js/locale/de.js
+++ b/js/locale/de.js
@@ -153,6 +153,7 @@ namespace("kivi").setupLocale({
 "Text block picture actions":"Aktionen für Textblockbilder",
 "The URL is missing.":"URL fehlt",
 "The action can only be executed once.":"Die Aktion kann nur einmal ausgeführt werden.",
+"The customer order number is missing. Do you want to continue anyway?":"Die Kundenbestellnummer fehlt. Möchten Sie trotzdem fortfahren?",
 "The description is missing.":"Die Beschreibung fehlt.",
 "The name is missing.":"Der Name fehlt.",
 "The name must only consist of letters, numbers and underscores and start with a letter.":"Der Name darf nur aus Buchstaben (keine Umlaute), Ziffern und Unterstrichen bestehen und muss mit einem Buchstaben beginnen.",
diff --git a/js/locale/en.js b/js/locale/en.js
index b03ddb34b..9c8738913 100644
--- a/js/locale/en.js
+++ b/js/locale/en.js
@@ -153,6 +153,7 @@ namespace("kivi").setupLocale({
 "Text block picture actions":"",
 "The URL is missing.":"",
 "The action can only be executed once.":"",
+"The customer order number is missing. Do you want to continue anyway?":"",
 "The description is missing.":"",
 "The name is missing.":"",
 "The name must only consist of letters, numbers and underscores and start with a letter.":"",
diff --git a/locale/de/all b/locale/de/all
index 3af730bbc..365c18c12 100755
--- a/locale/de/all
+++ b/locale/de/all
@@ -1694,6 +1694,7 @@ $self->{texts} = {
   'If enabled a warning will be shown in purchase delivery orders on workflow to invoices if positions are not stocked in.' => 'Falls aktiviert, wird eine Warnung beim Workflow von Einkaufslieferscheinen zu Rechnungen ausgegeben, wenn die Positionen noch nicht eingelagert sind.',
   'If enabled a warning will be shown in sales and purchase orders if there are two or more positions of the same part (new controller only).' => 'Falls eingeschaltet, wird eine Warnung angezeigt, wenn der Auftrag mehrere gleiche Artikel enthält (nur neuer Controller).',
   'If enabled a warning will be shown in sales and purchase orders if there the delivery date is empty.' => 'Falls aktiviert, Warnungen ausgeben sobald Aufträge (Einkauf- und Verkauf) keinen Liefertermin haben.',
+  'If enabled a warning will be shown in sales delivery orders if the customer order number is missing.' => 'Falls aktiviert, wird eine Warnung beim Speichern von Verkaufsaufträgen ausgegeben, wenn die Kundenbestellnummer fehlt.',
   'If enabled a warning will be shown in sales delivery orders on workflow to invoices if positions are not stocked out.' => 'Falls aktiviert, wird eine Warnung beim Workflow von Verkaufslieferscheinen zu Rechnungen ausgegeben, wenn die Positionen noch nicht ausgelagert sind.',
   'If enabled only those projects that are assigned to the currently selected customer are offered for selection in sales records.' => 'Wenn eingeschaltet, so werden in Verkaufsbelegen nur diejenigen Projekte zur Auswahl angeboten, die dem aktuell ausgewählten Kunden zugewiesen wurden.',
   'If enabled purchase and sales records cannot be saved if no transaction description has been entered.' => 'Wenn angeschaltet, so können Einkaufs- und Verkaufsbelege nicht gespeichert werden, solange keine Vorgangsbezeichnung eingegeben wurde.',
@@ -3460,6 +3461,7 @@ $self->{texts} = {
   'The custom variable has been saved.' => 'Die benutzerdefinierte Variable wurde gespeichert.',
   'The custom variable is in use and cannot be deleted.' => 'Die benutzerdefinierte Variable ist in Benutzung und kann nicht gelöscht werden.',
   'The customer name is missing.' => 'Der Kundenname fehlt.',
+  'The customer order number is missing. Do you want to continue anyway?' => 'Die Kundenbestellnummer fehlt. Möchten Sie trotzdem fortfahren?',
   'The customer\'s bank account number (IBAN) is missing.' => 'Die Kontonummer (IBAN) des Kunden fehlt.',
   'The database for user management and authentication does not exist. You can create let kivitendo create it with the following parameters:' => 'Die Datenbank für die Benutzeranmeldung existiert nicht. Sie können Sie von kivitendo automatisch mit den folgenden Parametern anlegen lassen:',
   'The database host is missing.' => 'Der Datenbankhost fehlt.',
@@ -4116,6 +4118,7 @@ $self->{texts} = {
   'Warehouses'                  => 'Lager',
   'Warn before saving orders with duplicate parts (new controller only)' => 'Beim Speichern warnen, wenn doppelte Artikel in einem Auftrag sind',
   'Warn before saving orders without a delivery date' => 'Warnung ausgeben, falls Aufträge kein Lieferdatum haben.',
+  'Warn before saving sales orders with missing customer order number (new controller only)' => 'Warnung ausgeben, falls Verkaufsaufträge keine Kundenbestellnummer haben',
   'Warning'                     => 'Warnung',
   'Warning! Loading a draft will discard unsaved data!' => 'Achtung! Beim Laden eines Entwurfs werden ungespeicherte Daten verworfen!',
   'Warning: Faulty position ignored' => 'Warnung: Fehlerhafte Artikel-Position ignoriert',
diff --git a/locale/en/all b/locale/en/all
index 9263032b0..973d4bd02 100644
--- a/locale/en/all
+++ b/locale/en/all
@@ -1694,6 +1694,7 @@ $self->{texts} = {
   'If enabled a warning will be shown in purchase delivery orders on workflow to invoices if positions are not stocked in.' => '',
   'If enabled a warning will be shown in sales and purchase orders if there are two or more positions of the same part (new controller only).' => '',
   'If enabled a warning will be shown in sales and purchase orders if there the delivery date is empty.' => '',
+  'If enabled a warning will be shown in sales delivery orders if the customer order number is missing.' => '',
   'If enabled a warning will be shown in sales delivery orders on workflow to invoices if positions are not stocked out.' => '',
   'If enabled only those projects that are assigned to the currently selected customer are offered for selection in sales records.' => '',
   'If enabled purchase and sales records cannot be saved if no transaction description has been entered.' => '',
@@ -3459,6 +3460,7 @@ $self->{texts} = {
   'The custom variable has been saved.' => '',
   'The custom variable is in use and cannot be deleted.' => '',
   'The customer name is missing.' => '',
+  'The customer order number is missing. Do you want to continue anyway?' => '',
   'The customer\'s bank account number (IBAN) is missing.' => '',
   'The database for user management and authentication does not exist. You can create let kivitendo create it with the following parameters:' => '',
   'The database host is missing.' => '',
@@ -4115,6 +4117,7 @@ $self->{texts} = {
   'Warehouses'                  => '',
   'Warn before saving orders with duplicate parts (new controller only)' => '',
   'Warn before saving orders without a delivery date' => '',
+  'Warn before saving sales orders with missing customer order number (new controller only)' => '',
   'Warning'                     => '',
   'Warning! Loading a draft will discard unsaved data!' => '',
   'Warning: Faulty position ignored' => '',
diff --git a/sql/Pg-upgrade2/defaults_order_warn_no_cusordnumber.sql b/sql/Pg-upgrade2/defaults_order_warn_no_cusordnumber.sql
new file mode 100644
index 000000000..e101bb0a5
--- /dev/null
+++ b/sql/Pg-upgrade2/defaults_order_warn_no_cusordnumber.sql
@@ -0,0 +1,5 @@
+-- @tag: defaults_order_warn_no_cusordnumber
+-- @description: Mandantenkonfiguration: Warnung bei fehlender Kundenbestellnummer in Verkaufsaufträgen
+-- @depends: release_3_5_8
+
+ALTER TABLE defaults ADD COLUMN order_warn_no_cusordnumber BOOLEAN DEFAULT FALSE;
diff --git a/templates/webpages/client_config/_features.html b/templates/webpages/client_config/_features.html
index fe22a7d3c..2b9adee9c 100644
--- a/templates/webpages/client_config/_features.html
+++ b/templates/webpages/client_config/_features.html
@@ -249,6 +249,11 @@
    <td>[% L.yes_no_tag("defaults.order_warn_no_deliverydate", SELF.defaults.order_warn_no_deliverydate) %]</td>
    <td>[% LxERP.t8("If enabled a warning will be shown in sales and purchase orders if there the delivery date is empty.") %]</td>
   </tr>
+  <tr>
+   <td align="right">[% LxERP.t8("Warn before saving sales orders with missing customer order number (new controller only)") %]</td>
+   <td>[% L.yes_no_tag("defaults.order_warn_no_cusordnumber", SELF.defaults.order_warn_no_cusordnumber) %]</td>
+   <td>[% LxERP.t8("If enabled a warning will be shown in sales delivery orders if the customer order number is missing.") %]</td>
+  </tr>
   <tr>
    <td align="right">[% LxERP.t8("For sales delivery orders, warn on workflow to invoice if not stocked out") %]</td>
    <td>[% L.yes_no_tag("defaults.sales_delivery_order_check_stocked", SELF.defaults.sales_delivery_order_check_stocked) %]</td>
