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>