Revision 4249ea44
Von Kivitendo Admin vor fast 10 Jahren hinzugefügt
SL/DB/Helper/AccountingPeriod.pm | ||
---|---|---|
1 |
package SL::DB::Helper::AccountingPeriod; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(Exporter); |
|
6 |
use SL::DBUtils; |
|
7 |
our @EXPORT = qw(get_balance_starting_date); |
|
8 |
|
|
9 |
use Carp; |
|
10 |
|
|
11 |
sub get_balance_starting_date { |
|
12 |
my ($self,$asofdate) = @_; |
|
13 |
|
|
14 |
$asofdate ||= DateTime->today_local; |
|
15 |
|
|
16 |
unless ( ref $asofdate eq 'DateTime' ) { |
|
17 |
$asofdate = $::locale->parse_date_to_object($asofdate); |
|
18 |
}; |
|
19 |
|
|
20 |
my $dbh = $::form->get_standard_dbh; |
|
21 |
|
|
22 |
my $startdate_method = $::instance_conf->get_balance_startdate_method; |
|
23 |
|
|
24 |
# We could use the following objects to determine the starting date for |
|
25 |
# calculating the balance from asofdate (the reference date for the balance): |
|
26 |
# * start_of_year - 1.1., no deviating fiscal year supported |
|
27 |
# * closed_to - all transactions since the books were last closed |
|
28 |
# * last_ob - all transactions since last opening balance transaction (usually 1.1.) |
|
29 |
# * mindate - all transactions in database |
|
30 |
|
|
31 |
my $start_of_year = $asofdate->clone(); |
|
32 |
$start_of_year->set_day(1); |
|
33 |
$start_of_year->set_month(1); |
|
34 |
|
|
35 |
# closedto assumes that we only close the books at the end of a fiscal year, |
|
36 |
# never during the fiscal year. If this assumption is valid closedto should |
|
37 |
# also work for deviating fiscal years. But as the trial balance (SuSa) |
|
38 |
# doesn't yet deal with deviating fiscal years, and it is useful to also close |
|
39 |
# the books after a month has been exported via DATEV, this method of |
|
40 |
# determining the starting date isn't recommended and is not the default. |
|
41 |
|
|
42 |
my $closedto = $::instance_conf->get_closedto; |
|
43 |
if ($closedto) { |
|
44 |
$closedto = $::locale->parse_date_to_object($closedto); |
|
45 |
$closedto->subtract(years => 1) while ($asofdate - $closedto)->is_negative; |
|
46 |
$closedto->add(days => 1); |
|
47 |
}; |
|
48 |
|
|
49 |
my ($query, $startdate, $last_ob, $mindate); |
|
50 |
$query = qq|select max(transdate) from acc_trans where ob_transaction is true and transdate <= ?|; |
|
51 |
($last_ob) = selectrow_query($::form, $dbh, $query, $::locale->format_date(\%::myconfig, $asofdate)); |
|
52 |
$last_ob = $::locale->parse_date_to_object($last_ob) if $last_ob; |
|
53 |
|
|
54 |
$query = qq|select min(transdate) from acc_trans|; |
|
55 |
($mindate) = selectrow_query($::form, $dbh, $query); |
|
56 |
$mindate = $::locale->parse_date_to_object($mindate); |
|
57 |
|
|
58 |
# the default method is to use all transactions ($mindate) |
|
59 |
|
|
60 |
if ( $startdate_method eq 'closed_to' and $closedto ) { |
|
61 |
# if no closedto is configured use default |
|
62 |
return $::locale->format_date(\%::myconfig, $closedto); |
|
63 |
|
|
64 |
} elsif ( $startdate_method eq 'start_of_year' ) { |
|
65 |
|
|
66 |
return $::locale->format_date(\%::myconfig, $start_of_year); |
|
67 |
|
|
68 |
} elsif ( $startdate_method eq 'all_transactions' ) { |
|
69 |
|
|
70 |
return $::locale->format_date(\%::myconfig, $mindate); |
|
71 |
|
|
72 |
} elsif ( $startdate_method eq 'last_ob_or_all_transactions' and $last_ob ) { |
|
73 |
# use default if there are no ob transactions |
|
74 |
|
|
75 |
return $::locale->format_date(\%::myconfig, $last_ob); |
|
76 |
|
|
77 |
} elsif ( $startdate_method eq 'last_ob_or_start_of_year' ) { |
|
78 |
|
|
79 |
if ( $last_ob ) { |
|
80 |
return $::locale->format_date(\%::myconfig, $last_ob); |
|
81 |
} else { |
|
82 |
return $::locale->format_date(\%::myconfig, $start_of_year); |
|
83 |
}; |
|
84 |
|
|
85 |
} else { |
|
86 |
# default action, also used for closedto and last_ob_or_all_transactions if |
|
87 |
# there are no valid dates |
|
88 |
|
|
89 |
return $::locale->format_date(\%::myconfig, $mindate); |
|
90 |
}; |
|
91 |
|
|
92 |
}; |
|
93 |
|
|
94 |
1; |
|
95 |
__END__ |
|
96 |
|
|
97 |
=pod |
|
98 |
|
|
99 |
=encoding utf8 |
|
100 |
|
|
101 |
=head1 NAME |
|
102 |
|
|
103 |
SL::DB::Helper::AccountingPeriod - Helper functions for calculating dates relative to the financial year |
|
104 |
|
|
105 |
=head1 FUNCTIONS |
|
106 |
|
|
107 |
=over 4 |
|
108 |
|
|
109 |
=item C<get_balance_starting_date $date> |
|
110 |
|
|
111 |
Given a date this method calculates and returns the starting date of the |
|
112 |
financial period relative to that date, according to the configured |
|
113 |
balance_startdate_method in the client configuration. The returned date is |
|
114 |
locale-formatted and can be used for SQL queries. |
|
115 |
|
|
116 |
If $date isn't a DateTime object a date string is assumed, which then gets |
|
117 |
date-parsed. |
|
118 |
|
|
119 |
If no argument is passed the current day is assumed as default. |
|
120 |
|
|
121 |
=back |
|
122 |
|
|
123 |
=head1 BUGS |
|
124 |
|
|
125 |
Nothing here yet. |
|
126 |
|
|
127 |
=head1 AUTHOR |
|
128 |
|
|
129 |
G. Richardson E<lt>information@kivitendo-premium.deE<gt> |
|
130 |
|
|
131 |
=cut |
SL/RP.pm | ||
---|---|---|
36 | 36 |
|
37 | 37 |
use SL::DBUtils; |
38 | 38 |
use Data::Dumper; |
39 |
use SL::DB::Helper::AccountingPeriod qw(get_balance_starting_date); |
|
39 | 40 |
use List::Util qw(sum); |
40 | 41 |
|
41 | 42 |
# use warnings; |
... | ... | |
50 | 51 |
# - proper testing for heading charts |
51 | 52 |
# - transmission from $form to TMPL realm is not as clear as i'd like |
52 | 53 |
|
53 |
sub get_balance_starting_date { |
|
54 |
|
|
55 |
# determine date from which the balance is calculated. The method is |
|
56 |
# configured in the client configuration. |
|
57 |
|
|
58 |
my $asofdate = shift; |
|
59 |
return unless $asofdate; |
|
60 |
|
|
61 |
$asofdate = $::locale->parse_date_to_object($asofdate); |
|
62 |
|
|
63 |
my $form = $main::form; |
|
64 |
my $dbh = $::form->get_standard_dbh; |
|
65 |
|
|
66 |
my $startdate_method = $::instance_conf->get_balance_startdate_method; |
|
67 |
|
|
68 |
# We could use the following objects to determine the starting date for |
|
69 |
# calculating the balance from asofdate (the reference date for the balance): |
|
70 |
# * start_of_year - 1.1., no deviating fiscal year supported |
|
71 |
# * closed_to - all transactions since the books were last closed |
|
72 |
# * last_ob - all transactions since last opening balance transaction (usually 1.1.) |
|
73 |
# * mindate - all transactions in database |
|
74 |
|
|
75 |
my $start_of_year = $asofdate->clone(); |
|
76 |
$start_of_year->set_day(1); |
|
77 |
$start_of_year->set_month(1); |
|
78 |
|
|
79 |
# closedto assumes that we only close the books at the end of a fiscal year, |
|
80 |
# never during the fiscal year. If this assumption is valid closedto should |
|
81 |
# also work for deviating fiscal years. But as the trial balance (SuSa) |
|
82 |
# doesn't yet deal with deviating fiscal years, and is useful to also close |
|
83 |
# the books after a month has been exported via DATEV, so this method of |
|
84 |
# determining the starting date isn't recommended and has been removed as |
|
85 |
# default. |
|
86 |
my ($closedto) = selectfirst_array_query($form, $dbh, 'SELECT closedto FROM defaults'); |
|
87 |
if ($closedto) { |
|
88 |
$closedto = $::locale->parse_date_to_object($closedto); |
|
89 |
$closedto->subtract(years => 1) while ($asofdate - $closedto)->is_negative; |
|
90 |
$closedto->add(days => 1); |
|
91 |
}; |
|
92 |
|
|
93 |
my ($query, $startdate, $last_ob, $mindate); |
|
94 |
$query = qq|select max(transdate) from acc_trans where ob_transaction is true and transdate <= ?|; |
|
95 |
($last_ob) = selectrow_query($::form, $dbh, $query, $::locale->format_date(\%::myconfig, $asofdate)); |
|
96 |
$last_ob = $::locale->parse_date_to_object($last_ob) if $last_ob; |
|
97 |
|
|
98 |
$query = qq|select min(transdate) from acc_trans|; |
|
99 |
($mindate) = selectrow_query($::form, $dbh, $query); |
|
100 |
$mindate = $::locale->parse_date_to_object($mindate); |
|
101 |
|
|
102 |
# the default method is to use all transactions ($mindate) |
|
103 |
|
|
104 |
if ( $startdate_method eq 'closed_to' and $closedto ) { |
|
105 |
# if no closedto is configured use default |
|
106 |
return $::locale->format_date(\%::myconfig, $closedto); |
|
107 |
|
|
108 |
} elsif ( $startdate_method eq 'start_of_year' ) { |
|
109 |
|
|
110 |
return $::locale->format_date(\%::myconfig, $start_of_year); |
|
111 |
|
|
112 |
} elsif ( $startdate_method eq 'all_transactions' ) { |
|
113 |
|
|
114 |
return $::locale->format_date(\%::myconfig, $mindate); |
|
115 |
|
|
116 |
} elsif ( $startdate_method eq 'last_ob_or_all_transactions' and $last_ob ) { |
|
117 |
# use default if there are no ob transactions |
|
118 |
|
|
119 |
return $::locale->format_date(\%::myconfig, $last_ob); |
|
120 |
|
|
121 |
} elsif ( $startdate_method eq 'last_ob_or_start_of_year' ) { |
|
122 |
|
|
123 |
if ( $last_ob ) { |
|
124 |
return $::locale->format_date(\%::myconfig, $last_ob); |
|
125 |
} else { |
|
126 |
return $::locale->format_date(\%::myconfig, $start_of_year); |
|
127 |
}; |
|
128 |
|
|
129 |
} else { |
|
130 |
# default action, also used for closedto and last_ob_or_all_transactions if |
|
131 |
# there are no valid dates |
|
132 |
|
|
133 |
return $::locale->format_date(\%::myconfig, $mindate); |
|
134 |
}; |
|
135 |
|
|
136 |
}; |
|
137 |
|
|
138 | 54 |
sub balance_sheet { |
139 | 55 |
$main::lxdebug->enter_sub(); |
140 | 56 |
|
57 |
my ($self) = @_; |
|
58 |
|
|
141 | 59 |
my $myconfig = \%main::myconfig; |
142 | 60 |
my $form = $main::form; |
143 | 61 |
my $dbh = $::form->get_standard_dbh; |
... | ... | |
151 | 69 |
} |
152 | 70 |
|
153 | 71 |
# get starting date for calculating balance |
154 |
$form->{this_startdate} = get_balance_starting_date($form->{asofdate}); |
|
72 |
$form->{this_startdate} = $self->get_balance_starting_date($form->{asofdate});
|
|
155 | 73 |
|
156 | 74 |
get_accounts($dbh, $last_period, $form->{this_startdate}, $form->{asofdate}, $form, \@categories); |
157 | 75 |
|
... | ... | |
159 | 77 |
if ($form->{compareasofdate}) { |
160 | 78 |
$last_period = 1; |
161 | 79 |
|
162 |
$form->{last_startdate} = get_balance_starting_date($form->{compareasofdate}); |
|
80 |
$form->{last_startdate} = $self->get_balance_starting_date($form->{compareasofdate});
|
|
163 | 81 |
|
164 | 82 |
get_accounts($dbh, $last_period, $form->{last_startdate} , $form->{compareasofdate}, $form, \@categories); |
165 | 83 |
$form->{last_period} = conv_dateq($form->{compareasofdate}); |
... | ... | |
926 | 844 |
# TODO dpt_where_without_arapgl and project - project calculation seems bogus anyway |
927 | 845 |
# TODO use fiscal_year_startdate for the whole trial balance |
928 | 846 |
# anyway, if the last booking is in a deviating fiscal year, this already improves the query |
929 |
my $fiscal_year_startdate = conv_dateq(get_balance_starting_date($form->{fromdate})); |
|
847 |
my $fiscal_year_startdate = conv_dateq($self->get_balance_starting_date($form->{fromdate}));
|
|
930 | 848 |
$fetch_accounts_before_from = qq|SELECT c.accno, c.description, c.category, SUM(ac.amount) AS amount |
931 | 849 |
FROM acc_trans ac JOIN chart c ON (c.id = ac.chart_id) WHERE 1 = 1 AND (ac.transdate <= $fromdate) |
932 | 850 |
AND (ac.transdate >= $fiscal_year_startdate) |
Auch abrufbar als: Unified diff
get_balance_starting_date nach SL/DB/Helper/AccountingPeriod.pm
neuer Helper, wohin die Funktion get_balance_starting_date aus SL/RP.pm
hin ausgelagert wurde. Wird auch im Chartpicker benutzt.