Einkaufs-/Verkaufsprozesse: optionale Einschränkungen für gewisse Aktionen
authorMoritz Bunkus <m.bunkus@linet-services.de>
Mon, 23 Jun 2014 14:38:16 +0000 (16:38 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Mon, 23 Jun 2014 14:38:16 +0000 (16:38 +0200)
Über die Mandantenkonfiguration kann verboten werden, dass gewisse
Aktionen in den Einkaufs- und Verkaufsprozesse durchgeführt
werden. Diese sind:

- Direkte umwandlung von Verkaufsangeboten und -aufträgen in
  Verkaufsrechnungen (nur über den Weg der Lieferscheine)
- Direktes Anlegen neuer Einkaufslieferscheine und -rechnungen (nur
  durch Umwandlung bestehender Belege)

SL/DB/MetaSetup/Default.pm
SL/Menu.pm
bin/mozilla/do.pl
bin/mozilla/ir.pl
bin/mozilla/oe.pl
locale/de/all
menus/erp.ini
sql/Pg-upgrade2/defaults_sales_process_limitations.sql [new file with mode: 0644]
templates/webpages/client_config/_features.html
templates/webpages/oe/form_footer.html

index 3c84351..5f924cd 100644 (file)
@@ -9,92 +9,96 @@ use base qw(SL::DB::Object);
 __PACKAGE__->meta->table('defaults');
 
 __PACKAGE__->meta->columns(
-  accounting_method                       => { type => 'text' },
-  address                                 => { type => 'text' },
-  ap_changeable                           => { type => 'integer', default => 2, not_null => 1 },
-  ap_show_mark_as_paid                    => { type => 'boolean', default => 'true' },
-  ar_changeable                           => { type => 'integer', default => 2, not_null => 1 },
-  ar_paid_accno_id                        => { type => 'integer' },
-  ar_show_mark_as_paid                    => { type => 'boolean', default => 'true' },
-  articlenumber                           => { type => 'text' },
-  assemblynumber                          => { type => 'text' },
-  balance_startdate_method                => { type => 'text' },
-  bin_id                                  => { type => 'integer' },
-  bin_id_ignore_onhand                    => { type => 'integer' },
-  businessnumber                          => { type => 'text' },
-  closedto                                => { type => 'date' },
-  cnnumber                                => { type => 'text' },
-  co_ustid                                => { type => 'text' },
-  coa                                     => { type => 'text' },
-  company                                 => { type => 'text' },
-  currency_id                             => { type => 'integer', not_null => 1 },
-  customer_hourly_rate                    => { type => 'numeric', precision => 8, scale => 2 },
-  customernumber                          => { type => 'text' },
-  datev_check_on_ap_transaction           => { type => 'boolean', default => 'true' },
-  datev_check_on_ar_transaction           => { type => 'boolean', default => 'true' },
-  datev_check_on_gl_transaction           => { type => 'boolean', default => 'true' },
-  datev_check_on_purchase_invoice         => { type => 'boolean', default => 'true' },
-  datev_check_on_sales_invoice            => { type => 'boolean', default => 'true' },
-  dunning_ar                              => { type => 'integer' },
-  dunning_ar_amount_fee                   => { type => 'integer' },
-  dunning_ar_amount_interest              => { type => 'integer' },
-  duns                                    => { type => 'text' },
-  expense_accno_id                        => { type => 'integer' },
-  fxgain_accno_id                         => { type => 'integer' },
-  fxloss_accno_id                         => { type => 'integer' },
-  gl_changeable                           => { type => 'integer', default => 2, not_null => 1 },
-  id                                      => { type => 'serial', not_null => 1 },
-  income_accno_id                         => { type => 'integer' },
-  inventory_accno_id                      => { type => 'integer' },
-  inventory_system                        => { type => 'text' },
-  invnumber                               => { type => 'text' },
-  ir_changeable                           => { type => 'integer', default => 2, not_null => 1 },
-  ir_show_mark_as_paid                    => { type => 'boolean', default => 'true' },
-  is_changeable                           => { type => 'integer', default => 2, not_null => 1 },
-  is_show_mark_as_paid                    => { type => 'boolean', default => 'true' },
-  itime                                   => { type => 'timestamp', default => 'now()' },
-  language_id                             => { type => 'integer' },
-  max_future_booking_interval             => { type => 'integer', default => 360 },
-  mtime                                   => { type => 'timestamp' },
-  normalize_part_descriptions             => { type => 'boolean', default => 'true' },
-  normalize_vc_names                      => { 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' },
-  parts_show_image                        => { type => 'boolean', default => 'true' },
-  payments_changeable                     => { type => 'integer', default => '0', not_null => 1 },
-  pdonumber                               => { type => 'text' },
-  ponumber                                => { type => 'text' },
-  profit_determination                    => { type => 'text' },
-  purchase_delivery_order_show_delete     => { type => 'boolean', default => 'true' },
-  purchase_order_show_delete              => { type => 'boolean', default => 'true' },
-  require_transaction_description_ps      => { type => 'boolean', default => 'false', not_null => 1 },
-  requirement_spec_section_order_part_id  => { type => 'integer' },
-  revtrans                                => { type => 'boolean', default => 'false' },
-  rfqnumber                               => { type => 'text' },
-  rmanumber                               => { type => 'text' },
-  sales_delivery_order_show_delete        => { type => 'boolean', default => 'true' },
-  sales_order_show_delete                 => { type => 'boolean', default => 'true' },
-  sdonumber                               => { type => 'text' },
-  sepa_creditor_id                        => { type => 'text' },
-  servicenumber                           => { type => 'text' },
-  show_bestbefore                         => { type => 'boolean', default => 'false' },
-  show_weight                             => { type => 'boolean', default => 'false', not_null => 1 },
-  signature                               => { type => 'text' },
-  sonumber                                => { type => 'text' },
-  sqnumber                                => { type => 'text' },
-  taxnumber                               => { type => 'text' },
-  templates                               => { type => 'text' },
-  transfer_default                        => { type => 'boolean', default => 'true' },
-  transfer_default_ignore_onhand          => { type => 'boolean', default => 'false' },
-  transfer_default_use_master_default_bin => { type => 'boolean', default => 'false' },
-  vendornumber                            => { type => 'text' },
-  version                                 => { type => 'varchar', length => 8 },
-  vertreter                               => { type => 'boolean', default => 'false' },
-  warehouse_id                            => { type => 'integer' },
-  warehouse_id_ignore_onhand              => { type => 'integer' },
-  webdav                                  => { type => 'boolean', default => 'false' },
-  webdav_documents                        => { type => 'boolean', default => 'false' },
-  weightunit                              => { type => 'varchar', length => 5 },
+  accounting_method                        => { type => 'text' },
+  address                                  => { type => 'text' },
+  allow_new_purchase_delivery_order        => { type => 'boolean', default => 'true', not_null => 1 },
+  allow_new_purchase_invoice               => { type => 'boolean', default => 'true', not_null => 1 },
+  allow_sales_invoice_from_sales_order     => { type => 'boolean', default => 'true', not_null => 1 },
+  allow_sales_invoice_from_sales_quotation => { type => 'boolean', default => 'true', not_null => 1 },
+  ap_changeable                            => { type => 'integer', default => 2, not_null => 1 },
+  ap_show_mark_as_paid                     => { type => 'boolean', default => 'true' },
+  ar_changeable                            => { type => 'integer', default => 2, not_null => 1 },
+  ar_paid_accno_id                         => { type => 'integer' },
+  ar_show_mark_as_paid                     => { type => 'boolean', default => 'true' },
+  articlenumber                            => { type => 'text' },
+  assemblynumber                           => { type => 'text' },
+  balance_startdate_method                 => { type => 'text' },
+  bin_id                                   => { type => 'integer' },
+  bin_id_ignore_onhand                     => { type => 'integer' },
+  businessnumber                           => { type => 'text' },
+  closedto                                 => { type => 'date' },
+  cnnumber                                 => { type => 'text' },
+  co_ustid                                 => { type => 'text' },
+  coa                                      => { type => 'text' },
+  company                                  => { type => 'text' },
+  currency_id                              => { type => 'integer', not_null => 1 },
+  customer_hourly_rate                     => { type => 'numeric', precision => 8, scale => 2 },
+  customernumber                           => { type => 'text' },
+  datev_check_on_ap_transaction            => { type => 'boolean', default => 'true' },
+  datev_check_on_ar_transaction            => { type => 'boolean', default => 'true' },
+  datev_check_on_gl_transaction            => { type => 'boolean', default => 'true' },
+  datev_check_on_purchase_invoice          => { type => 'boolean', default => 'true' },
+  datev_check_on_sales_invoice             => { type => 'boolean', default => 'true' },
+  dunning_ar                               => { type => 'integer' },
+  dunning_ar_amount_fee                    => { type => 'integer' },
+  dunning_ar_amount_interest               => { type => 'integer' },
+  duns                                     => { type => 'text' },
+  expense_accno_id                         => { type => 'integer' },
+  fxgain_accno_id                          => { type => 'integer' },
+  fxloss_accno_id                          => { type => 'integer' },
+  gl_changeable                            => { type => 'integer', default => 2, not_null => 1 },
+  id                                       => { type => 'serial', not_null => 1 },
+  income_accno_id                          => { type => 'integer' },
+  inventory_accno_id                       => { type => 'integer' },
+  inventory_system                         => { type => 'text' },
+  invnumber                                => { type => 'text' },
+  ir_changeable                            => { type => 'integer', default => 2, not_null => 1 },
+  ir_show_mark_as_paid                     => { type => 'boolean', default => 'true' },
+  is_changeable                            => { type => 'integer', default => 2, not_null => 1 },
+  is_show_mark_as_paid                     => { type => 'boolean', default => 'true' },
+  itime                                    => { type => 'timestamp', default => 'now()' },
+  language_id                              => { type => 'integer' },
+  max_future_booking_interval              => { type => 'integer', default => 360 },
+  mtime                                    => { type => 'timestamp' },
+  normalize_part_descriptions              => { type => 'boolean', default => 'true' },
+  normalize_vc_names                       => { 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' },
+  parts_show_image                         => { type => 'boolean', default => 'true' },
+  payments_changeable                      => { type => 'integer', default => '0', not_null => 1 },
+  pdonumber                                => { type => 'text' },
+  ponumber                                 => { type => 'text' },
+  profit_determination                     => { type => 'text' },
+  purchase_delivery_order_show_delete      => { type => 'boolean', default => 'true' },
+  purchase_order_show_delete               => { type => 'boolean', default => 'true' },
+  require_transaction_description_ps       => { type => 'boolean', default => 'false', not_null => 1 },
+  requirement_spec_section_order_part_id   => { type => 'integer' },
+  revtrans                                 => { type => 'boolean', default => 'false' },
+  rfqnumber                                => { type => 'text' },
+  rmanumber                                => { type => 'text' },
+  sales_delivery_order_show_delete         => { type => 'boolean', default => 'true' },
+  sales_order_show_delete                  => { type => 'boolean', default => 'true' },
+  sdonumber                                => { type => 'text' },
+  sepa_creditor_id                         => { type => 'text' },
+  servicenumber                            => { type => 'text' },
+  show_bestbefore                          => { type => 'boolean', default => 'false' },
+  show_weight                              => { type => 'boolean', default => 'false', not_null => 1 },
+  signature                                => { type => 'text' },
+  sonumber                                 => { type => 'text' },
+  sqnumber                                 => { type => 'text' },
+  taxnumber                                => { type => 'text' },
+  templates                                => { type => 'text' },
+  transfer_default                         => { type => 'boolean', default => 'true' },
+  transfer_default_ignore_onhand           => { type => 'boolean', default => 'false' },
+  transfer_default_use_master_default_bin  => { type => 'boolean', default => 'false' },
+  vendornumber                             => { type => 'text' },
+  version                                  => { type => 'varchar', length => 8 },
+  vertreter                                => { type => 'boolean', default => 'false' },
+  warehouse_id                             => { type => 'integer' },
+  warehouse_id_ignore_onhand               => { type => 'integer' },
+  webdav                                   => { type => 'boolean', default => 'false' },
+  webdav_documents                         => { type => 'boolean', default => 'false' },
+  weightunit                               => { type => 'varchar', length => 5 },
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
index 06ea6ee..19b2d2d 100644 (file)
@@ -162,6 +162,11 @@ sub parse_access_string {
   return SL::Auth::evaluate_rights_ary($stack[0]);
 }
 
+sub parse_instance_conf_string {
+  my ($self, $setting) = @_;
+  return $::instance_conf->data->{$setting};
+}
+
 sub set_access {
   my $self = shift;
 
@@ -171,6 +176,7 @@ sub set_access {
     my $entry = $self->{$key};
 
     $entry->{GRANTED}              = $entry->{ACCESS} ? $self->parse_access_string($key, $entry->{ACCESS}) : 1;
+    $entry->{GRANTED}            &&= $self->parse_instance_conf_string($entry->{INSTANCE_CONF}) if $entry->{INSTANCE_CONF};
     $entry->{IS_MENU}              = $entry->{submenu} || ($key !~ m/--/);
     $entry->{NUM_VISIBLE_CHILDREN} = 0;
 
index 67f2740..88ae6c3 100644 (file)
@@ -85,6 +85,10 @@ sub add {
 
   check_do_access();
 
+  if (($::form->{type} =~ /purchase/) && !$::instance_conf->get_allow_new_purchase_invoice) {
+    $::form->show_generic_error($::locale->text("You do not have the permissions to access this function."));
+  }
+
   my $form     = $main::form;
 
   set_headings("add");
index e90b12c..951bce5 100644 (file)
@@ -58,6 +58,10 @@ sub add {
 
   $main::auth->assert('vendor_invoice_edit');
 
+  if (!$::instance_conf->get_allow_new_purchase_invoice) {
+    $::form->show_generic_error($::locale->text("You do not have the permissions to access this function."));
+  }
+
   return $main::lxdebug->leave_sub() if (load_draft_maybe());
 
   $form->{title} = $locale->text('Record Vendor Invoice');
index d6d8ff4..12a7446 100644 (file)
@@ -90,6 +90,16 @@ sub check_oe_access {
   $main::auth->assert($right);
 }
 
+sub check_oe_conversion_to_sales_invoice_allowed {
+  return 1 if  $::form->{type} !~ m/^sales/;
+  return 1 if ($::form->{type} =~ m/quotation/) && $::instance_conf->get_allow_sales_invoice_from_sales_quotation;
+  return 1 if ($::form->{type} =~ m/order/)     && $::instance_conf->get_allow_sales_invoice_from_sales_order;
+
+  $::form->show_generic_error($::locale->text("You do not have the permissions to access this function."));
+
+  return 0;
+}
+
 sub set_headings {
   $main::lxdebug->enter_sub();
 
@@ -1313,6 +1323,7 @@ sub invoice {
   my $locale   = $main::locale;
 
   check_oe_access();
+  check_oe_conversion_to_sales_invoice_allowed();
   $main::auth->assert($form->{type} eq 'purchase_order' || $form->{type} eq 'request_quotation' ? 'vendor_invoice_edit' : 'invoice_edit');
 
   $form->{old_salesman_id} = $form->{salesman_id};
index c4200bb..c5c1e83 100755 (executable)
@@ -208,6 +208,10 @@ $self->{texts} = {
   'All units have either no or exactly one base unit of which they are multiples.' => 'Einheiten haben entweder keine oder genau eine Basiseinheit, von der sie ein Vielfaches sind.',
   'All users'                   => 'Alle BenutzerInnen',
   'Allow access'                => 'Zugriff erlauben',
+  'Allow conversion from sales orders to sales invoices' => 'Umwandlung von Verkaufsaufträgen in Verkaufsrechnungen zulassen',
+  'Allow conversion from sales quotations to sales invoices' => 'Umwandlung von Verkaufsangeboten in Verkaufsrechnungen zulassen',
+  'Allow direct creation of new purchase delivery orders' => 'Direktes Anlegen neuer Einkaufslieferscheine zulassen',
+  'Allow direct creation of new purchase invoices' => 'Direktes Anlegen neuer Einkaufsrechnungen zulassen',
   'Allow the following users access to my follow-ups:' => 'Erlaube den folgenden Benutzern Zugriff auf meine Wiedervorlagen:',
   'Alternatively you can create a new part which will then be selected.' => 'Sie k&ouml;nnen auch einen neuen Artikel anlegen, der dann automatisch ausgew&auml;hlt wird.',
   'Amended Advance Turnover Tax Return' => 'Berichtigte Anmeldung',
@@ -1192,6 +1196,10 @@ $self->{texts} = {
   'If amounts differ more than "Maximal amount difference" (see settings), this item is marked as invalid.' => 'Weichen die Beträge mehr als die "maximale Betragsabweichung" (siehe Einstellungen) ab, so wird diese Position als ungültig markiert.',
   'If checked the taxkey will not be exported in the DATEV Export, but only IF chart taxkeys differ from general ledger taxkeys' => 'Falls angehakt wird der DATEV-Steuerschlüssel bei Buchungen auf dieses Konto nicht beim DATEV-Export mitexportiert, allerdings nur wenn zusätzlich der Konto-Steuerschlüssel vom Buchungs (Hauptbuch) Steuerschlüssel abweicht',
   'If configured this bin will be preselected for all new parts. Also this bin will be used as the master default bin, if default transfer out with master bin is activated.' => 'Falls konfiguriert, wird dieses Lager mit Lagerplatz für neu angelegte Waren vorausgewählt.',
+  'If disabled purchase delivery orders can only be created by conversion from existing requests for quotations and purchase orders.' => 'Falls deaktiviert, so können Einkaufslieferscheine nur durch Umwandlung aus bestehenden Preisanfragen und Lieferantenaufträgen angelegt werden.',
+  'If disabled purchase invoices can only be created by conversion from existing requests for quotations, purchase orders and purchase delivery orders.' => 'Falls deaktiviert, so können Einkaufsrechnungen nur durch Umwandlung aus bestehenden Preisanfragen, Lieferantenaufträgen und Einkaufslieferscheinen angelegt werden.',
+  'If disabled sales orders cannot be converted into sales invoices directly.' => 'Falls deaktiviert, so können Verkaufsangebote nicht direkt in Verkaufsrechnungen umgewandelt werden.',
+  'If disabled sales quotations cannot be converted into sales invoices directly.' => 'Falls deaktiviert, so können Verkaufsauträge nicht direkt in Verkaufsrechnungen umgewandelt werden.',
   '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.',
   'If missing then the start date will be used.' => 'Falls es fehlt, so wird die erste Rechnung für das Startdatum erzeugt.',
   'If the article type is set to \'mixed\' then a column called \'type\' must be present.' => 'Falls der Artikeltyp auf \'gemischt\' gestellt wird, muss eine Spalte namens \'type\' vorhanden sein.',
index dd43bdf..fde2dd8 100644 (file)
@@ -214,12 +214,14 @@ type=purchase_order
 
 [AP--Add Delivery Note]
 ACCESS=purchase_delivery_order_edit
+INSTANCE_CONF=allow_new_purchase_delivery_order
 module=do.pl
 action=add
 type=purchase_delivery_order
 
 [AP--Add Vendor Invoice]
 ACCESS=vendor_invoice_edit
+INSTANCE_CONF=allow_new_purchase_invoice
 module=ir.pl
 action=add
 type=invoice
diff --git a/sql/Pg-upgrade2/defaults_sales_process_limitations.sql b/sql/Pg-upgrade2/defaults_sales_process_limitations.sql
new file mode 100644 (file)
index 0000000..f62cb71
--- /dev/null
@@ -0,0 +1,27 @@
+-- @tag: defaults_sales_purchase_process_limitations
+-- @description: Mandantenkonfiguration: Einschränkungen, welche Aktionen im Einkaufs-/Verkaufsprozess erlaubt sind
+-- @depends: release_3_1_0
+ALTER TABLE defaults
+  ADD COLUMN allow_sales_invoice_from_sales_quotation BOOLEAN,
+  ADD COLUMN allow_sales_invoice_from_sales_order     BOOLEAN,
+  ADD COLUMN allow_new_purchase_delivery_order        BOOLEAN,
+  ADD COLUMN allow_new_purchase_invoice               BOOLEAN;
+
+UPDATE defaults
+SET allow_sales_invoice_from_sales_quotation = TRUE,
+    allow_sales_invoice_from_sales_order     = TRUE,
+    allow_new_purchase_delivery_order        = TRUE,
+    allow_new_purchase_invoice               = TRUE;
+
+ALTER TABLE defaults
+  ALTER COLUMN allow_sales_invoice_from_sales_quotation SET DEFAULT TRUE,
+  ALTER COLUMN allow_sales_invoice_from_sales_quotation SET NOT NULL,
+
+  ALTER COLUMN allow_sales_invoice_from_sales_order     SET DEFAULT TRUE,
+  ALTER COLUMN allow_sales_invoice_from_sales_order     SET NOT NULL,
+
+  ALTER COLUMN allow_new_purchase_delivery_order        SET DEFAULT TRUE,
+  ALTER COLUMN allow_new_purchase_delivery_order        SET NOT NULL,
+
+  ALTER COLUMN allow_new_purchase_invoice               SET DEFAULT TRUE,
+  ALTER COLUMN allow_new_purchase_invoice               SET NOT NULL;
index af14bb9..79ae72e 100644 (file)
    <td>[% LxERP.t8('If enabled purchase and sales records cannot be saved if no transaction description has been entered.') %]</td>
   </tr>
 
+  <tr>
+   <td align="right">[% LxERP.t8('Allow conversion from sales quotations to sales invoices') %]</td>
+   <td>[% L.yes_no_tag('defaults.allow_sales_invoice_from_sales_quotation', SELF.defaults.allow_sales_invoice_from_sales_quotation) %]</td>
+   <td>[% LxERP.t8('If disabled sales quotations cannot be converted into sales invoices directly.') %]</td>
+  </tr>
+
+  <tr>
+   <td align="right">[% LxERP.t8('Allow conversion from sales orders to sales invoices') %]</td>
+   <td>[% L.yes_no_tag('defaults.allow_sales_invoice_from_sales_order', SELF.defaults.allow_sales_invoice_from_sales_order) %]</td>
+   <td>[% LxERP.t8('If disabled sales orders cannot be converted into sales invoices directly.') %]</td>
+  </tr>
+
+  <tr>
+   <td align="right">[% LxERP.t8('Allow direct creation of new purchase delivery orders') %]</td>
+   <td>[% L.yes_no_tag('defaults.allow_new_purchase_delivery_order', SELF.defaults.allow_new_purchase_delivery_order) %]</td>
+   <td>[% LxERP.t8('If disabled purchase delivery orders can only be created by conversion from existing requests for quotations and purchase orders.') %]</td>
+  </tr>
+
+  <tr>
+   <td align="right">[% LxERP.t8('Allow direct creation of new purchase invoices') %]</td>
+   <td>[% L.yes_no_tag('defaults.allow_new_purchase_invoice', SELF.defaults.allow_new_purchase_invoice) %]</td>
+   <td>[% LxERP.t8('If disabled purchase invoices can only be created by conversion from existing requests for quotations, purchase orders and purchase delivery orders.') %]</td>
+  </tr>
+
   <tr><td class="listheading" colspan="4">[% LxERP.t8("Requirement Specs") %]</td></tr>
 
   <tr>
index b082bf2..9dd893e 100644 (file)
@@ -2,6 +2,15 @@
 [%- USE HTML %]
 [%- USE LxERP %]
 [%- USE L %]
+[%- IF is_req_quo || is_pur_ord %]
+  [%- SET allow_invoice=1 %]
+[%- ELSIF is_sales_quo && INSTANCE_CONF.get_allow_sales_invoice_from_sales_quotation %]
+  [%- SET allow_invoice=1 %]
+[%- ELSIF is_sales_ord && INSTANCE_CONF.get_allow_sales_invoice_from_sales_order %]
+  [%- SET allow_invoice=1 %]
+[%- ELSE %]
+  [%- SET allow_invoice=0 %]
+[%- END %]
   <tr>
     <td>
       <table width="100%">
     <input class="submit" type="submit" name="action_delivery_order" value="[% 'Delivery Order' | $T8 %]">
   [%- END %]
 
+  [%- IF allow_invoice %]
   <input class="submit" type="submit" name="action_invoice" value="[% 'Invoice' | $T8 %]">
+  [%- END %]
 
   [%- IF is_sales_ord || is_pur_ord %]
     <br>[% heading %] als neue Vorlage verwenden f&uuml;r<br>