From: Moritz Bunkus Date: Thu, 5 Feb 2015 12:38:07 +0000 (+0100) Subject: Wiederkehrende Rechnungen: Auftragswerts-Periodizität setzen können X-Git-Tag: release-3.2.1~53^2~9 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=82ff5451c8babb72b4963f8d3bbb4b604a3b4675;p=kivitendo-erp.git Wiederkehrende Rechnungen: Auftragswerts-Periodizität setzen können Noch keine Anpassung der eigentlichen Berechnung. Wohl aber Dokumentation von SL::DB::PeriodicInvoicesConfig. --- diff --git a/SL/BackgroundJob/CreatePeriodicInvoices.pm b/SL/BackgroundJob/CreatePeriodicInvoices.pm index d80ba4eeb..e782d821b 100644 --- a/SL/BackgroundJob/CreatePeriodicInvoices.pm +++ b/SL/BackgroundJob/CreatePeriodicInvoices.pm @@ -74,7 +74,7 @@ sub _log_msg { sub _generate_time_period_variables { my $config = shift; my $period_start_date = shift; - my $period_end_date = $period_start_date->clone->truncate(to => 'month')->add(months => $config->get_period_length)->subtract(days => 1); + my $period_end_date = $period_start_date->clone->truncate(to => 'month')->add(months => $config->get_billing_period_length)->subtract(days => 1); my @month_names = ('', $::locale->text('January'), $::locale->text('February'), $::locale->text('March'), $::locale->text('April'), $::locale->text('May'), $::locale->text('June'), diff --git a/SL/Controller/FinancialControllingReport.pm b/SL/Controller/FinancialControllingReport.pm index c10c09dbe..8ac846428 100644 --- a/SL/Controller/FinancialControllingReport.pm +++ b/SL/Controller/FinancialControllingReport.pm @@ -148,7 +148,7 @@ sub calculate_periodic_invoices_order_netamount { $cur_date->add(years => 1); } - return $num_years * $order->netamount * (12 / $order->periodic_invoices_config->get_period_length); + return $num_years * $order->netamount * (12 / $order->periodic_invoices_config->get_billing_period_length); } sub sum_items { diff --git a/SL/Controller/FinancialOverview.pm b/SL/Controller/FinancialOverview.pm index cd153d23f..6b2889932 100644 --- a/SL/Controller/FinancialOverview.pm +++ b/SL/Controller/FinancialOverview.pm @@ -148,7 +148,7 @@ sub calculate_one_periodic_invoice { return if $params{config}->start_date > $params{end_date}; my $first_date = $params{config}->start_date->clone->set_year($self->year); - my $net = $params{config}->order->netamount * (12 / $params{config}->get_period_length); + my $net = $params{config}->order->netamount * (12 / $params{config}->get_billing_period_length); my $sord = $self->data->{sales_orders}; $sord->{months }->[ $first_date->month - 1 ] += $net; diff --git a/SL/DB/MetaSetup/PeriodicInvoicesConfig.pm b/SL/DB/MetaSetup/PeriodicInvoicesConfig.pm index eae8481d4..1aeb42fd7 100644 --- a/SL/DB/MetaSetup/PeriodicInvoicesConfig.pm +++ b/SL/DB/MetaSetup/PeriodicInvoicesConfig.pm @@ -17,7 +17,8 @@ __PACKAGE__->meta->columns( first_billing_date => { type => 'date' }, id => { type => 'integer', not_null => 1, sequence => 'id' }, oe_id => { type => 'integer', not_null => 1 }, - periodicity => { type => 'varchar', length => 10, not_null => 1 }, + order_value_periodicity => { type => 'varchar', length => 1, not_null => 1 }, + periodicity => { type => 'varchar', length => 1, not_null => 1 }, print => { type => 'boolean', default => 'false' }, printer_id => { type => 'integer' }, start_date => { type => 'date' }, diff --git a/SL/DB/PeriodicInvoicesConfig.pm b/SL/DB/PeriodicInvoicesConfig.pm index 8013cd940..53ac1c679 100644 --- a/SL/DB/PeriodicInvoicesConfig.pm +++ b/SL/DB/PeriodicInvoicesConfig.pm @@ -11,14 +11,22 @@ __PACKAGE__->meta->initialize; # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all. __PACKAGE__->meta->make_manager_class; -our @PERIODICITIES = qw(m q f b y); -our %PERIOD_LENGTHS = ( m => 1, q => 3, f => 4, b => 6, y => 12 ); +our %PERIOD_LENGTHS = ( m => 1, q => 3, b => 6, y => 12 ); +our %ORDER_VALUE_PERIOD_LENGTHS = ( %PERIOD_LENGTHS, 2 => 24, 3 => 36, 4 => 48, 5 => 60 ); +our @PERIODICITIES = keys %PERIOD_LENGTHS; +our @ORDER_VALUE_PERIODICITIES = keys %ORDER_VALUE_PERIOD_LENGTHS; -sub get_period_length { +sub get_billing_period_length { my $self = shift; return $PERIOD_LENGTHS{ $self->periodicity } || 1; } +sub get_order_value_period_length { + my $self = shift; + return $self->get_billing_period_length if $self->order_value_periodicity eq 'p'; + return $ORDER_VALUE_PERIOD_LENGTHS{ $self->order_value_periodicity } || 1; +} + sub _log_msg { $::lxdebug->message(LXDebug->DEBUG1(), join('', @_)); } @@ -78,7 +86,7 @@ SQL sub calculate_invoice_dates { my ($self, %params) = @_; - my $period_len = $self->get_period_length; + my $period_len = $self->get_billing_period_length; my $cur_date = $self->first_billing_date || $self->start_date; my $end_date = $self->terminated ? $self->end_date : undef; $end_date //= DateTime->today_local->add(years => 100); @@ -100,3 +108,98 @@ sub calculate_invoice_dates { } 1; +__END__ + +=pod + +=encoding utf8 + +=head1 NAME + +SL::DB::PeriodicInvoicesConfig - DB model for the configuration for periodic invoices + +=head1 FUNCTIONS + +=over 4 + +=item C + +Calculates dates for which invoices will have to be created. Returns a +list of L objects. + +This function looks at the configuration settings and at the list of +invoices that have already been created for this configuration. The +date range for which dates are created are controlled by several +values: + +=over 2 + +=item * The properties C and C +determine the start date. + +=item * The properties C and C determine the end +date. + +=item * The optional parameter C determines whether or not +dates for which invoices have already been created will be included in +the list. The default is not to include them. + +=item * The optional parameters C and C override +the start and end dates from the configuration. + +=item * If no end date is set or implied via the configuration and no +C parameter is given then the function will use 100 years +in the future as the end date. + +=back + +=item C + +Returns the number of months corresponding to the billing +periodicity. This means that a new invoice has to be created every x +months starting with the value in C (or +C if C is unset). + +=item C + +Returns the number of months the order's value refers to. This looks +at the C. + +Each invoice's value is calculated as C. + +=item C + +Returns the highest date (as an instance of L) for which an +invoice has been created from this configuration. + +=item C + +Configurations which haven't been terminated and which have an end +date set may be eligible for automatic extension by a certain number +of months. This what the function implements. + +If the configuration is not eligible or if the C hasn't been +reached yet then nothing is done and C is returned. Otherwise +its behavior is determined by the C property. + +If the property C is not 0 then the +C will be extended by C months, and +the configuration will be saved. In this case the new end date will be +returned. + +Otherwise (if C is 0) the property C +will be set to 1, and the configuration will be saved. In this case +C will be returned. + +=back + +=head1 BUGS + +Nothing here yet. + +=head1 AUTHOR + +Moritz Bunkus Em.bunkus@linet-services.deE + +=cut diff --git a/SL/OE.pm b/SL/OE.pm index 061cd27a0..9944f71cd 100644 --- a/SL/OE.pm +++ b/SL/OE.pm @@ -738,7 +738,7 @@ sub load_periodic_invoice_config { my $config_obj = SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $form->{id}); if ($config_obj) { - my $config = { map { $_ => $config_obj->$_ } qw(active terminated periodicity start_date_as_date end_date_as_date first_billing_date_as_date extend_automatically_by ar_chart_id + my $config = { map { $_ => $config_obj->$_ } qw(active terminated periodicity order_value_periodicity start_date_as_date end_date_as_date first_billing_date_as_date extend_automatically_by ar_chart_id print printer_id copies) }; $form->{periodic_invoices_config} = YAML::Dump($config); } diff --git a/bin/mozilla/oe.pl b/bin/mozilla/oe.pl index 4483deb1f..147e9d9de 100644 --- a/bin/mozilla/oe.pl +++ b/bin/mozilla/oe.pl @@ -2000,14 +2000,16 @@ sub edit_periodic_invoices_config { $config = YAML::Load($::form->{periodic_invoices_config}) if $::form->{periodic_invoices_config}; if ('HASH' ne ref $config) { - $config = { periodicity => 'y', + $config = { periodicity => 'm', + order_value_periodicity => 'p', # = same as periodicity start_date_as_date => $::form->{transdate} || $::form->current_date, extend_automatically_by => 12, active => 1, }; } - $config->{periodicity} = 'm' if none { $_ eq $config->{periodicity} } qw(m q b y); + $config->{periodicity} = 'm' if none { $_ eq $config->{periodicity} } @SL::DB::PeriodicInvoicesConfig::PERIODICITIES; + $config->{order_value_periodicity} = 'p' if none { $_ eq $config->{order_value_periodicity} } ('p', @SL::DB::PeriodicInvoicesConfig::ORDER_VALUE_PERIODICITIES); $::form->get_lists(printers => "ALL_PRINTERS", charts => { key => 'ALL_CHARTS', @@ -2033,7 +2035,8 @@ sub save_periodic_invoices_config { my $config = { active => $::form->{active} ? 1 : 0, terminated => $::form->{terminated} ? 1 : 0, - periodicity => (any { $_ eq $::form->{periodicity} } qw(m q b y)) ? $::form->{periodicity} : 'm', + periodicity => (any { $_ eq $::form->{periodicity} } @SL::DB::PeriodicInvoicesConfig::PERIODICITIES) ? $::form->{periodicity} : 'm', + order_value_periodicity => (any { $_ eq $::form->{order_value_periodicity} } ('p', @SL::DB::PeriodicInvoicesConfig::ORDER_VALUE_PERIODICITIES)) ? $::form->{order_value_periodicity} : 'p', start_date_as_date => $::form->{start_date_as_date}, end_date_as_date => $::form->{end_date_as_date}, first_billing_date_as_date => $::form->{first_billing_date_as_date}, diff --git a/locale/de/all b/locale/de/all index e0b5e0de0..3f8177e72 100755 --- a/locale/de/all +++ b/locale/de/all @@ -35,9 +35,13 @@ $self->{texts} = { '...on the TODO list' => '...auf der Aufgabenliste', '0% tax with taxkey' => '0% Steuer mit Steuerschlüssel ', '1. Quarter' => '1. Quartal', + '2 years' => '2 Jahre', '2. Quarter' => '2. Quartal', + '3 years' => '3 Jahre', '3. Quarter' => '3. Quartal', + '4 years' => '4 Jahre', '4. Quarter' => '4. Quartal', + '5 years' => '5 Jahre', ' I DO CARE! Please check create warehouse and bins and define a name for the warehouse (Bins will be created automatically) and then continue' => 'ICH KÜMMER MICH Bitte haken Sie Lager und Lagerplätze erzeugen an (Automatisches Zuweisen der Lagerplätze) und vergeben einen Namen für dieses Lager (Lagerplätze werden automatisch übernommen). Danach auf weiter.', ' I DO CARE! Please click back and cancel the update and come back after there has been at least one warehouse defined with bin(s).:' => 'ICH KÜMMER MICH Brechen Sie das Update ab und legen selber mindestens ein Lager mit Lagerplätzen unter dem Menü System / Lager an.', ' I DO NOT CARE Please click continue and the following data (see list) will be deleted:' => 'IST MIR EGAL Mit einem Klick auf Weiter (rot) werden keine Daten übernommen, bzw. migriert und die folgende Information in der untenstehenden Liste wird gelöscht.', @@ -354,6 +358,7 @@ $self->{texts} = { 'Billed amount' => 'Abgerechneter Betrag', 'Billed extra expenses' => 'Abgerechnete Nebenkosten', 'Billing Address' => 'Rechnungsadresse', + 'Billing Periodicity' => 'Abrechnungsperiodizität', 'Billing/shipping address (city)' => 'Rechnungsadresse (Stadt)', 'Billing/shipping address (country)' => 'Rechnungsadresse (Land)', 'Billing/shipping address (street)' => 'Rechnungsadresse (Straße)', @@ -1731,6 +1736,7 @@ $self->{texts} = { 'Order deleted!' => 'Auftrag gelöscht!', 'Order probability' => 'Auftragswahrscheinlichkeit', 'Order probability & expected billing date' => 'Auftragswahrscheinlichkeit & vorrauss. Abrechnungsdatum', + 'Order value periodicity' => 'Auftragswert basiert auf Periodizität', 'Order/Item row name' => 'Name der Auftrag-/Positions-Zeilen', 'OrderItem' => 'Position', 'Ordered' => 'Von Kunden bestellt', @@ -1821,7 +1827,6 @@ $self->{texts} = { 'Periodic inventory' => 'Aufwandsmethode', 'Periodic invoices active' => 'Wiederkehrende Rechnungen aktiv', 'Periodic invoices inactive' => 'Wiederkehrende Rechnungen inaktiv', - 'Periodicity' => 'Periodizität', 'Perpetual inventory' => 'Bestandsmethode', 'Person' => 'Person', 'Personal settings' => 'Persönliche Einstellungen', @@ -3240,6 +3245,7 @@ $self->{texts} = { 'sales_order' => 'Kundenauftrag', 'sales_order_list' => 'auftragsliste', 'sales_quotation' => 'Verkaufsangebot', + 'same as periodicity' => 'stimmt mit Abrechnungsperiodizität überein', 'saved' => 'gespeichert', 'saved!' => 'gespeichert', 'saving data' => 'Speichere Daten', diff --git a/sql/Pg-upgrade2/periodic_invoices_order_value_periodicity.sql b/sql/Pg-upgrade2/periodic_invoices_order_value_periodicity.sql new file mode 100644 index 000000000..d2db1d593 --- /dev/null +++ b/sql/Pg-upgrade2/periodic_invoices_order_value_periodicity.sql @@ -0,0 +1,26 @@ +-- @tag: periodic_invoices_order_value_periodicity +-- @description: Wiederkehrende Rechnungen: Einstellung für Periode, auf die sich der Auftragswert bezieht +-- @depends: release_3_1_0 + +-- Spalte »periodicity«: nur ein Zeichen, und Check auf gültige Werte +ALTER TABLE periodic_invoices_configs +ADD CONSTRAINT periodic_invoices_configs_valid_periodicity +CHECK (periodicity IN ('m', 'q', 'b', 'y')); + +ALTER TABLE periodic_invoices_configs +ALTER COLUMN periodicity TYPE varchar(1); + +-- Neue Spalte »order_value_periodicity« +ALTER TABLE periodic_invoices_configs +ADD COLUMN order_value_periodicity varchar(1); + +UPDATE periodic_invoices_configs +SET order_value_periodicity = 'p'; + +ALTER TABLE periodic_invoices_configs +ALTER COLUMN order_value_periodicity +SET NOT NULL; + +ALTER TABLE periodic_invoices_configs +ADD CONSTRAINT periodic_invoices_configs_valid_order_value_periodicity +CHECK (order_value_periodicity IN ('p', 'm', 'q', 'b', 'y', '2', '3', '4', '5')); diff --git a/templates/webpages/oe/edit_periodic_invoices_config.html b/templates/webpages/oe/edit_periodic_invoices_config.html index 093cf0574..656dc4326 100644 --- a/templates/webpages/oe/edit_periodic_invoices_config.html +++ b/templates/webpages/oe/edit_periodic_invoices_config.html @@ -1,6 +1,7 @@ [% USE HTML %] [% USE LxERP %] [% USE L %] +[% SET style="width: 400px" %]

[% title %]

@@ -20,15 +21,19 @@ - [%- LxERP.t8('Periodicity') %] + [%- LxERP.t8('Billing Periodicity') %] - [% L.radio_button_tag("periodicity", value => "m", label => LxERP.t8("monthly"), checked => periodicity == 'm') %] -
- [% L.radio_button_tag("periodicity", value => "q", label => LxERP.t8("every third month"), checked => periodicity == 'q') %] -
- [% L.radio_button_tag("periodicity", value => "b", label => LxERP.t8("semiannually"), checked => periodicity == 'b') %] -
- [% L.radio_button_tag("periodicity", value => "y", label => LxERP.t8("yearly"), checked => periodicity == 'y') %] + [% L.select_tag("periodicity", [ [ "m", LxERP.t8("monthly") ], [ "q", LxERP.t8("every third month") ], [ "b", LxERP.t8("semiannually") ], [ "y", LxERP.t8("yearly") ] ], default=periodicity, style=style) %] + + + + + [%- LxERP.t8('Order value periodicity') %] + + [% L.select_tag("order_value_periodicity", + [ [ "p", LxERP.t8("same as periodicity") ], [ "m", LxERP.t8("monthly") ], [ "q", LxERP.t8("every third month") ], [ "b", LxERP.t8("semiannually") ], [ "y", LxERP.t8("yearly") ], + [ "2", LxERP.t8("2 years") ], [ "3", LxERP.t8("3 years") ], [ "4", LxERP.t8("4 years") ], [ "5", LxERP.t8("5 years") ], ], + default=order_value_periodicity, style=style) %] @@ -63,7 +68,7 @@ [%- LxERP.t8('Record in') %] - [% L.select_tag("ar_chart_id", AR, title_key => 'description', default => ar_chart_id) %] + [% L.select_tag("ar_chart_id", AR, title_key => 'description', default => ar_chart_id, style=style) %] @@ -77,7 +82,7 @@ [%- LxERP.t8('Printer') %] - [% L.select_tag("printer_id", ALL_PRINTERS, title_key = 'printer_description', default = printer_id, disabled = !print) %] + [% L.select_tag("printer_id", ALL_PRINTERS, title_key = 'printer_description', default = printer_id, disabled = !print, style=style) %]