From: Moritz Bunkus Date: Mon, 23 Jun 2014 14:38:16 +0000 (+0200) Subject: Einkaufs-/Verkaufsprozesse: optionale Einschränkungen für gewisse Aktionen X-Git-Tag: release-3.2.0beta~411^2~22 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=f775b88a24af70fd667683ee235adc2d450e83b9;p=kivitendo-erp.git Einkaufs-/Verkaufsprozesse: optionale Einschränkungen für gewisse Aktionen Ü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) --- diff --git a/SL/DB/MetaSetup/Default.pm b/SL/DB/MetaSetup/Default.pm index 3c84351d6..5f924cdf9 100644 --- a/SL/DB/MetaSetup/Default.pm +++ b/SL/DB/MetaSetup/Default.pm @@ -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' ]); diff --git a/SL/Menu.pm b/SL/Menu.pm index 06ea6ee43..19b2d2d16 100644 --- a/SL/Menu.pm +++ b/SL/Menu.pm @@ -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; diff --git a/bin/mozilla/do.pl b/bin/mozilla/do.pl index 67f2740c5..88ae6c387 100644 --- a/bin/mozilla/do.pl +++ b/bin/mozilla/do.pl @@ -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"); diff --git a/bin/mozilla/ir.pl b/bin/mozilla/ir.pl index e90b12cf6..951bce515 100644 --- a/bin/mozilla/ir.pl +++ b/bin/mozilla/ir.pl @@ -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'); diff --git a/bin/mozilla/oe.pl b/bin/mozilla/oe.pl index d6d8ff4d5..12a74464a 100644 --- a/bin/mozilla/oe.pl +++ b/bin/mozilla/oe.pl @@ -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}; diff --git a/locale/de/all b/locale/de/all index c4200bb04..c5c1e83c3 100755 --- a/locale/de/all +++ b/locale/de/all @@ -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önnen auch einen neuen Artikel anlegen, der dann automatisch ausgewä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.', diff --git a/menus/erp.ini b/menus/erp.ini index dd43bdf8c..fde2dd8c4 100644 --- a/menus/erp.ini +++ b/menus/erp.ini @@ -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 index 000000000..f62cb71c0 --- /dev/null +++ b/sql/Pg-upgrade2/defaults_sales_process_limitations.sql @@ -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; diff --git a/templates/webpages/client_config/_features.html b/templates/webpages/client_config/_features.html index af14bb98b..79ae72e37 100644 --- a/templates/webpages/client_config/_features.html +++ b/templates/webpages/client_config/_features.html @@ -65,6 +65,30 @@ [% LxERP.t8('If enabled purchase and sales records cannot be saved if no transaction description has been entered.') %] + + [% LxERP.t8('Allow conversion from sales quotations to sales invoices') %] + [% L.yes_no_tag('defaults.allow_sales_invoice_from_sales_quotation', SELF.defaults.allow_sales_invoice_from_sales_quotation) %] + [% LxERP.t8('If disabled sales quotations cannot be converted into sales invoices directly.') %] + + + + [% LxERP.t8('Allow conversion from sales orders to sales invoices') %] + [% L.yes_no_tag('defaults.allow_sales_invoice_from_sales_order', SELF.defaults.allow_sales_invoice_from_sales_order) %] + [% LxERP.t8('If disabled sales orders cannot be converted into sales invoices directly.') %] + + + + [% LxERP.t8('Allow direct creation of new purchase delivery orders') %] + [% L.yes_no_tag('defaults.allow_new_purchase_delivery_order', SELF.defaults.allow_new_purchase_delivery_order) %] + [% LxERP.t8('If disabled purchase delivery orders can only be created by conversion from existing requests for quotations and purchase orders.') %] + + + + [% LxERP.t8('Allow direct creation of new purchase invoices') %] + [% L.yes_no_tag('defaults.allow_new_purchase_invoice', SELF.defaults.allow_new_purchase_invoice) %] + [% LxERP.t8('If disabled purchase invoices can only be created by conversion from existing requests for quotations, purchase orders and purchase delivery orders.') %] + + [% LxERP.t8("Requirement Specs") %] diff --git a/templates/webpages/oe/form_footer.html b/templates/webpages/oe/form_footer.html index b082bf25c..9dd893e8d 100644 --- a/templates/webpages/oe/form_footer.html +++ b/templates/webpages/oe/form_footer.html @@ -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 %] @@ -157,7 +166,9 @@ [%- END %] + [%- IF allow_invoice %] + [%- END %] [%- IF is_sales_ord || is_pur_ord %]
[% heading %] als neue Vorlage verwenden für