1 package SL::DB::Helper::AccountingPeriod;
4 use SL::Locale::String qw(t8);
6 use parent qw(Exporter);
8 our @EXPORT = qw(get_balance_starting_date get_balance_startdate_method_options);
12 sub get_balance_startdate_method_options {
14 { title => t8("After closed period"), value => "closed_to" },
15 { title => t8("Start of year"), value => "start_of_year" },
16 { title => t8("All transactions"), value => "all_transactions" },
17 { title => t8("Last opening balance or all transactions"), value => "last_ob_or_all_transactions" },
18 { title => t8("Last opening balance or start of year"), value => "last_ob_or_start_of_year" },
22 sub get_balance_starting_date {
23 my ($self, $asofdate, $startdate_method) = @_;
25 $asofdate ||= DateTime->today_local;
26 $startdate_method ||= $::instance_conf->get_balance_startdate_method;
28 unless ( ref $asofdate eq 'DateTime' ) {
29 $asofdate = $::locale->parse_date_to_object($asofdate);
32 my $dbh = $::form->get_standard_dbh;
35 # We could use the following objects to determine the starting date for
36 # calculating the balance from asofdate (the reference date for the balance):
37 # * start_of_year - 1.1., no deviating fiscal year supported
38 # * closed_to - all transactions since the books were last closed
39 # * last_ob - all transactions since last opening balance transaction (usually 1.1.)
40 # * mindate - all transactions in database
42 my $start_of_year = $asofdate->clone();
43 $start_of_year->set_day(1);
44 $start_of_year->set_month(1);
46 # closedto assumes that we only close the books at the end of a fiscal year,
47 # never during the fiscal year. If this assumption is valid closedto should
48 # also work for deviating fiscal years. But as the trial balance (SuSa)
49 # doesn't yet deal with deviating fiscal years, and it is useful to also close
50 # the books after a month has been exported via DATEV, this method of
51 # determining the starting date isn't recommended and is not the default.
53 my $closedto = $::instance_conf->get_closedto;
55 $closedto = $::locale->parse_date_to_object($closedto);
56 $closedto->subtract(years => 1) while ($asofdate - $closedto)->is_negative;
57 $closedto->add(days => 1);
60 my ($query, $startdate, $last_ob, $mindate);
61 $query = qq|select max(transdate) from acc_trans where ob_transaction is true and transdate <= ?|;
62 ($last_ob) = selectrow_query($::form, $dbh, $query, $::locale->format_date(\%::myconfig, $asofdate));
63 $last_ob = $::locale->parse_date_to_object($last_ob) if $last_ob;
65 $query = qq|select min(transdate) from acc_trans|;
66 ($mindate) = selectrow_query($::form, $dbh, $query);
67 $mindate = $::locale->parse_date_to_object($mindate);
69 # the default method is to use all transactions ($mindate)
71 if ( $startdate_method eq 'closed_to' and $closedto ) {
72 # if no closedto is configured use default
73 return $::locale->format_date(\%::myconfig, $closedto);
75 } elsif ( $startdate_method eq 'start_of_year' ) {
77 return $::locale->format_date(\%::myconfig, $start_of_year);
79 } elsif ( $startdate_method eq 'all_transactions' ) {
81 return $::locale->format_date(\%::myconfig, $mindate);
83 } elsif ( $startdate_method eq 'last_ob_or_all_transactions' and $last_ob ) {
84 # use default if there are no ob transactions
86 return $::locale->format_date(\%::myconfig, $last_ob);
88 } elsif ( $startdate_method eq 'last_ob_or_start_of_year' ) {
91 return $::locale->format_date(\%::myconfig, $last_ob);
93 return $::locale->format_date(\%::myconfig, $start_of_year);
97 # default action, also used for closedto and last_ob_or_all_transactions if
98 # there are no valid dates
100 return $::locale->format_date(\%::myconfig, $mindate);
114 SL::DB::Helper::AccountingPeriod - Helper functions for calculating dates relative to the financial year
120 =item C<get_balance_startdate_method_options>
122 Returns an arrayref of translated options for determining the startdate of a
123 balance period or the yearend period. To be used as the options for a dropdown.
125 =item C<get_balance_starting_date $date $startdate_method>
127 Given a date this method calculates and returns the starting date of the
128 financial period relative to that date, according to the configured
129 balance_startdate_method in the client configuration. The returned date is
130 locale-formatted and can be used for SQL queries.
132 If $date isn't a DateTime object a date string is assumed, which then gets
135 If no argument is passed the current day is assumed as default.
137 If no startdate method is passed, the default method from defaults is used.
147 G. Richardson E<lt>information@kivitendo-premium.deE<gt>