Revision 8165bc52
Von Moritz Bunkus vor etwa 11 Jahren hinzugefügt
SL/Controller/FinancialOverview.pm | ||
---|---|---|
1 |
package SL::Controller::FinancialOverview; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::Controller::Base); |
|
5 |
|
|
6 |
use List::MoreUtils qw(none); |
|
7 |
|
|
8 |
use SL::DB::Invoice; |
|
9 |
use SL::DB::Order; |
|
10 |
use SL::DB::PurchaseInvoice; |
|
11 |
use SL::Controller::Helper::ReportGenerator; |
|
12 |
use SL::Locale::String; |
|
13 |
|
|
14 |
use Rose::Object::MakeMethods::Generic ( |
|
15 |
scalar => [ qw(report number_columns year current_year types objects data subtotals_per_quarter) ], |
|
16 |
); |
|
17 |
|
|
18 |
__PACKAGE__->run_before(sub { $::auth->assert('report'); }); |
|
19 |
|
|
20 |
sub action_list { |
|
21 |
my ($self) = @_; |
|
22 |
|
|
23 |
$self->subtotals_per_quarter($::form->{subtotals_per_quarter}); |
|
24 |
|
|
25 |
$self->get_objects; |
|
26 |
$self->calculate_data; |
|
27 |
$self->prepare_report; |
|
28 |
$self->list_data; |
|
29 |
} |
|
30 |
|
|
31 |
# private functions |
|
32 |
|
|
33 |
sub prepare_report { |
|
34 |
my ($self) = @_; |
|
35 |
|
|
36 |
$self->report(SL::ReportGenerator->new(\%::myconfig, $::form)); |
|
37 |
|
|
38 |
my @columns = qw(year quarter month sales_quotations sales_orders sales_invoices requests_for_quotation purchase_orders purchase_invoices); |
|
39 |
|
|
40 |
$self->number_columns([ grep { !m/^(?:month|year|quarter)$/ } @columns ]); |
|
41 |
|
|
42 |
my %column_defs = ( |
|
43 |
month => { text => t8('Month') }, |
|
44 |
year => { text => t8('Year') }, |
|
45 |
quarter => { text => t8('Quarter') }, |
|
46 |
sales_quotations => { text => t8('Sales Quotations') }, |
|
47 |
sales_orders => { text => t8('Sales Orders') }, |
|
48 |
sales_invoices => { text => t8('Invoices') }, |
|
49 |
requests_for_quotation => { text => t8('Requests for Quotation') }, |
|
50 |
purchase_orders => { text => t8('Purchase Orders') }, |
|
51 |
purchase_invoices => { text => t8('Purchase Invoices') }, |
|
52 |
); |
|
53 |
|
|
54 |
map { $column_defs{$_}->{align} = 'right' } @columns; |
|
55 |
|
|
56 |
$self->report->set_options( |
|
57 |
std_column_visibility => 1, |
|
58 |
controller_class => 'FinancialOverview', |
|
59 |
output_format => 'HTML', |
|
60 |
raw_top_info_text => $self->render('financial_overview/report_top', { output => 0 }, YEARS_TO_LIST => [ reverse(2000..$self->current_year) ]), |
|
61 |
title => t8('Financial overview for #1', $self->year), |
|
62 |
allow_pdf_export => 1, |
|
63 |
allow_csv_export => 1, |
|
64 |
); |
|
65 |
$self->report->set_columns(%column_defs); |
|
66 |
$self->report->set_column_order(@columns); |
|
67 |
$self->report->set_export_options(qw(list year subtotals_per_quarter)); |
|
68 |
$self->report->set_options_from_form; |
|
69 |
} |
|
70 |
|
|
71 |
sub get_objects { |
|
72 |
my ($self) = @_; |
|
73 |
|
|
74 |
$self->current_year(DateTime->today->year); |
|
75 |
$self->year($::form->{year} || DateTime->today->year); |
|
76 |
|
|
77 |
my $start = DateTime->new(year => $self->year, month => 1, day => 1); |
|
78 |
my $end = DateTime->new(year => $self->year, month => 12, day => 31); |
|
79 |
|
|
80 |
my @date_filter = (and => [ transdate => { ge => $start }, transdate => { le => $end } ]); |
|
81 |
|
|
82 |
$self->objects({ |
|
83 |
sales_quotations => SL::DB::Manager::Order->get_all( where => [ and => [ @date_filter, SL::DB::Manager::Order->type_filter('sales_quotation') ]]), |
|
84 |
sales_orders => SL::DB::Manager::Order->get_all( where => [ and => [ @date_filter, SL::DB::Manager::Order->type_filter('sales_order') ]]), |
|
85 |
requests_for_quotation => SL::DB::Manager::Order->get_all( where => [ and => [ @date_filter, SL::DB::Manager::Order->type_filter('request_quotation') ]]), |
|
86 |
purchase_orders => SL::DB::Manager::Order->get_all( where => [ and => [ @date_filter, SL::DB::Manager::Order->type_filter('purchase_order') ]]), |
|
87 |
sales_invoices => SL::DB::Manager::Invoice->get_all( where => \@date_filter), |
|
88 |
purchase_invoices => SL::DB::Manager::PurchaseInvoice->get_all(where => \@date_filter), |
|
89 |
}); |
|
90 |
} |
|
91 |
|
|
92 |
sub calculate_data { |
|
93 |
my ($self) = @_; |
|
94 |
|
|
95 |
$self->types([ qw(sales_quotations sales_orders sales_invoices requests_for_quotation purchase_orders purchase_invoices) ]); |
|
96 |
|
|
97 |
my %data = ( |
|
98 |
year => [ ($self->year) x 12 ], |
|
99 |
month => [ (1..12) ], |
|
100 |
quarter => [ (1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4) ], |
|
101 |
map { |
|
102 |
$_ => { |
|
103 |
months => [ (0) x 12 ], |
|
104 |
quarters => [ (0) x 4 ], |
|
105 |
year => 0, |
|
106 |
} |
|
107 |
} @{ $self->types }, |
|
108 |
); |
|
109 |
|
|
110 |
foreach my $type (keys %{ $self->objects }) { |
|
111 |
foreach my $object (@{ $self->objects->{ $type } }) { |
|
112 |
my $month = $object->transdate->month - 1; |
|
113 |
my $tdata = $data{$type}; |
|
114 |
|
|
115 |
$tdata->{months}->[$month] += $object->netamount; |
|
116 |
$tdata->{quarters}->[int($month / 3)] += $object->netamount; |
|
117 |
$tdata->{year} += $object->netamount; |
|
118 |
} |
|
119 |
} |
|
120 |
|
|
121 |
$self->data(\%data); |
|
122 |
} |
|
123 |
|
|
124 |
sub list_data { |
|
125 |
my ($self) = @_; |
|
126 |
|
|
127 |
my @visible_columns = $self->report->get_visible_columns; |
|
128 |
my @type_columns = @{ $self->types }; |
|
129 |
my @non_type_columns = grep { my $c = $_; none { $c eq $_ } @type_columns } @visible_columns; |
|
130 |
|
|
131 |
for my $month (1..12) { |
|
132 |
my %data = ( |
|
133 |
map({ ($_ => { data => $self->data->{$_}->[$month - 1] }) } @non_type_columns), |
|
134 |
map({ ($_ => { data => $::form->format_amount(\%::myconfig, $self->data->{$_}->{months}->[$month - 1]) }) } @type_columns ), |
|
135 |
); |
|
136 |
|
|
137 |
$self->report->add_data(\%data); |
|
138 |
|
|
139 |
if ($self->subtotals_per_quarter && (($month % 3) == 0)) { |
|
140 |
my %subtotal = ( |
|
141 |
year => { data => $self->year }, |
|
142 |
month => { data => $::locale->text('Total') }, |
|
143 |
map { ($_ => { data => $::form->format_amount(\%::myconfig, $self->data->{$_}->{quarters}->[int(($month - 1) / 3)]) }) } @type_columns, |
|
144 |
); |
|
145 |
|
|
146 |
$subtotal{$_}->{class} = 'listsubtotal' for @visible_columns; |
|
147 |
|
|
148 |
$self->report->add_data(\%subtotal); |
|
149 |
} |
|
150 |
} |
|
151 |
|
|
152 |
my %data = ( |
|
153 |
year => { data => $self->year }, |
|
154 |
quarter => { data => $::locale->text('Total') }, |
|
155 |
map { ($_ => { data => $::form->format_amount(\%::myconfig, $self->data->{$_}->{year}) }) } @type_columns, |
|
156 |
); |
|
157 |
|
|
158 |
$data{$_}->{class} = 'listtotal' for @visible_columns; |
|
159 |
|
|
160 |
$self->report->add_data(\%data); |
|
161 |
|
|
162 |
return $self->report->generate_with_headers; |
|
163 |
} |
|
164 |
|
|
165 |
1; |
locale/de/all | ||
---|---|---|
569 | 569 |
'Current profile' => 'Aktuelles Profil', |
570 | 570 |
'Current status' => 'Aktueller Status', |
571 | 571 |
'Current value:' => 'Aktueller Wert:', |
572 |
'Current year' => 'Aktuelles Jahr', |
|
572 | 573 |
'Custom Variables' => 'Benutzerdefinierte Variablen', |
573 | 574 |
'Custom variables for module' => 'Benutzerdefinierte Variablen für Modul', |
574 | 575 |
'Customer' => 'Kunde', |
... | ... | |
964 | 965 |
'Filter for customer variables' => 'Filter für benutzerdefinierte Kundenvariablen', |
965 | 966 |
'Filter for item variables' => 'Filter für benutzerdefinierte Artikelvariablen', |
966 | 967 |
'Filter parts' => 'Artikel filtern', |
968 |
'Financial Controlling' => 'Finanzcontrolling', |
|
969 |
'Financial Controlling Report' => 'Finanzcontrollingbericht', |
|
970 |
'Financial Overview' => 'Finanzübersicht', |
|
971 |
'Financial controlling report for open sales orders' => 'Finanzcontrollingbericht für offene Aufträge', |
|
972 |
'Financial overview for #1' => 'Finanzübersicht für #1', |
|
967 | 973 |
'Finish' => 'Abschließen', |
968 | 974 |
'First 20 Lines' => 'Nur erste 20 Datensätze', |
969 | 975 |
'Fix transaction' => 'Buchung korrigieren', |
... | ... | |
978 | 984 |
'Follow-Up saved.' => 'Wiedervorlage gespeichert.', |
979 | 985 |
'Follow-Ups' => 'Wiedervorlagen', |
980 | 986 |
'Follow-up for' => 'Wiedervorlage für', |
987 |
'Following year' => 'Folgendes Jahr', |
|
981 | 988 |
'Font' => 'Schriftart', |
982 | 989 |
'Font size' => 'Schriftgröße', |
983 | 990 |
'For AP transactions it will replace the sales taxkeys with input taxkeys with the same tax rate.' => 'Bei Kreditorenbuchungen werden die Umsatzsteuer-Steuerschlüssel durch Vorsteuer-Steuerschlüssel mit demselben Steuersatz ersetzt.', |
... | ... | |
1629 | 1636 |
'Printer Management' => 'Druckeradministration', |
1630 | 1637 |
'Printer management' => 'Druckerverwaltung', |
1631 | 1638 |
'Printing ... ' => 'Es wird gedruckt.', |
1639 |
'Prior year' => 'Vorheriges Jahr', |
|
1632 | 1640 |
'Private E-mail' => 'Private E-Mail', |
1633 | 1641 |
'Private Phone' => 'Privates Tel.', |
1634 | 1642 |
'Problem' => 'Problem', |
... | ... | |
1737 | 1745 |
'Requested execution date' => 'Gewünschtes Ausführungsdatum', |
1738 | 1746 |
'Requested execution date from' => 'Gewünschtes Ausführungsdatum von', |
1739 | 1747 |
'Requested execution date to' => 'Gewünschtes Ausführungsdatum bis', |
1748 |
'Requests for Quotation' => 'Preisanfragen', |
|
1740 | 1749 |
'Required by' => 'Lieferdatum', |
1741 | 1750 |
'Reset' => 'Zurücksetzen', |
1742 | 1751 |
'Result' => 'Ergebnis', |
... | ... | |
1968 | 1977 |
'Subject:' => 'Betreff:', |
1969 | 1978 |
'Subtotal' => 'Zwischensumme', |
1970 | 1979 |
'Subtotal cannot distinguish betweens record types. Only one of the selected record types will be displayed: #1' => 'Zwischensummen können nicht zwischen den einzelnen Belegen unterscheiden, es wird nur "#1" angezeigt', |
1980 |
'Subtotals per quarter' => 'Zwischensummen pro Quartal', |
|
1971 | 1981 |
'Such entries cannot be exported into the DATEV format and have to be fixed as well.' => 'Solche Einträge sind aber nicht DATEV-exportiertbar und müssen ebenfalls korrigiert werden.', |
1972 | 1982 |
'Sum Credit' => 'Summe Haben', |
1973 | 1983 |
'Sum Debit' => 'Summe Soll', |
menus/erp.ini | ||
---|---|---|
414 | 414 |
action=report |
415 | 415 |
report=projects |
416 | 416 |
|
417 |
[Reports--Financial Overview] |
|
418 |
ACCESS=report |
|
419 |
module=controller.pl |
|
420 |
action=FinancialOverview/list |
|
421 |
|
|
417 | 422 |
|
418 | 423 |
[Batch Printing] |
419 | 424 |
ACCESS=batch_printing |
templates/webpages/financial_overview/report_top.html | ||
---|---|---|
1 |
[%- USE L %][% USE LxERP %] |
|
2 |
<form method="post" id="form" action="controller.pl"> |
|
3 |
[% L.hidden_tag('action', 'FinancialOverview/list') %] |
|
4 |
<a href="[% SELF.url_for(action='list', year=(SELF.year - 1), subtotals_per_quarter=SELF.subtotals_per_quarter) %]">« [%- LxERP.t8("Prior year") %]: [% SELF.year - 1 %]</a> |
|
5 |
| |
|
6 |
|
|
7 |
[% LxERP.t8("Current year") %]: |
|
8 |
[% L.select_tag('year', YEARS_TO_LIST, default=SELF.year, onchange='$("#form").submit();') %] |
|
9 |
|
|
10 |
[% IF SELF.year < SELF.current_year %] |
|
11 |
| |
|
12 |
<a href="[% SELF.url_for(action='list', year=(SELF.year + 1), subtotals_per_quarter=SELF.subtotals_per_quarter) %]">[%- LxERP.t8("Following year") %]: [% SELF.year + 1 %] »</a> |
|
13 |
[% END %] |
|
14 |
|
|
15 |
<br> |
|
16 |
[% L.checkbox_tag('subtotals_per_quarter', checked=SELF.subtotals_per_quarter, label=LxERP.t8('Subtotals per quarter'), onchange='$("#form").submit();') %] |
|
17 |
</form> |
|
18 |
<hr> |
Auch abrufbar als: Unified diff
Finanzübersichtsbericht: Finanzübersichtsbericht: erste Implementation