gnucash/libgnucash/engine/gnc-accounting-period.c
John Ralls 4ae17d12c7 [options] Move options from app-utils to engine.
Options is required for book options that are stored as part of the data
 file and so belongs in engine.
2022-08-25 22:09:56 -07:00

324 lines
9.1 KiB
C

/*
* gnc-accounting-period.c --
*
* Copyright (c) 2005 David Hampton <hampton@employees.org>
* All rights reserved.
*
* GnuCash is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Gnucash is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
/** @addtogroup GUI
@{ */
/** @file gnc-accounting-period.c
@brief General utilities for dealing with accounting periods.
@author David Hampton <hampton@employees.org>
These are general utility functions for specifying an accounting
period and converting it to a value usable by the gnucash engine.
The choice of src/app-utils is arbitrary as these utilities don't
fit well anywhere else. They are at a higher level than a GDate,
so they don't fit in src/core-utils/gnc-gdate-utils.c. They don't
operate on engine data structures, so they don't belong in
src/engine/Period.c. Putting them into src/engine/gnc-date.c
would be the best place for them, but then that creates a new
dependency from the src/engine directory to the src/core-utils
directory that doesn't currently exist. Since that might be a
problem for CashUtils, the app-file directory was chosen.
*/
#include <config.h>
#include <string.h>
#include "gnc-accounting-period.h"
#include "gnc-date.h"
#include "gnc-prefs.h"
#include "qof.h"
#include "gnc-session.h"
static const QofLogModule log_module = G_LOG_DOMAIN;
static time64 gnc_accounting_period_start_time64 (GncAccountingPeriod which,
const GDate *fy_end,
const GDate *contains);
static time64 gnc_accounting_period_end_time64 (GncAccountingPeriod which,
const GDate *fy_end,
const GDate *contains);
static time64
lookup_start_date_option (GDate *fy_end)
{
time64 time;
int which;
if (gnc_prefs_get_bool (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_CHOICE_ABS))
time = gnc_time64_get_day_start (gnc_prefs_get_int64
(GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_DATE));
else
{
which = gnc_prefs_get_int (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_PERIOD);
time = gnc_accounting_period_start_time64 (which, fy_end, NULL);
}
/* we will need the balance of the last transaction before the start
date, so subtract 1 from start date */
/* CAS: we don't actually do what this comment says. I think that's
because a bug in the engine has been fixed. */
return time;
}
static time64
lookup_end_date_option (GDate *fy_end)
{
time64 time;
int which;
if (gnc_prefs_get_bool (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_CHOICE_ABS))
time = gnc_time64_get_day_end (gnc_prefs_get_int64
(GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_DATE));
else
{
which = gnc_prefs_get_int (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_PERIOD);
time = gnc_accounting_period_end_time64 (which, fy_end, NULL);
}
if (time == 0)
time = -1;
return time;
}
static GDate *
get_fy_end (void)
{
QofBook *book;
GDate *date = NULL;
book = qof_session_get_book(gnc_get_current_session());
qof_instance_get (QOF_INSTANCE (book), "fy-end", &date, NULL);
return date;
}
time64
gnc_accounting_period_fiscal_start (void)
{
time64 t;
GDate *fy_end = get_fy_end();
t = lookup_start_date_option (fy_end);
if (fy_end)
g_date_free (fy_end);
return t;
}
time64
gnc_accounting_period_fiscal_end (void)
{
time64 t;
GDate *fy_end = get_fy_end();
t = lookup_end_date_option (fy_end);
if (fy_end)
g_date_free (fy_end);
return t;
}
GDate *
gnc_accounting_period_start_gdate (GncAccountingPeriod which,
const GDate *fy_end,
const GDate *contains)
{
GDate *date;
if (contains)
{
date = g_date_new_dmy (g_date_get_day (contains),
g_date_get_month (contains),
g_date_get_year (contains));
}
else
{
date = g_date_new ();
gnc_gdate_set_today (date);
}
switch (which)
{
default:
PINFO ("Undefined relative time constant %d", which);
g_date_free (date);
return NULL;
case GNC_ACCOUNTING_PERIOD_TODAY:
/* Already have today's date */
break;
case GNC_ACCOUNTING_PERIOD_MONTH:
gnc_gdate_set_month_start (date);
break;
case GNC_ACCOUNTING_PERIOD_MONTH_PREV:
gnc_gdate_set_prev_month_start (date);
break;
case GNC_ACCOUNTING_PERIOD_QUARTER:
gnc_gdate_set_quarter_start (date);
break;
case GNC_ACCOUNTING_PERIOD_QUARTER_PREV:
gnc_gdate_set_prev_quarter_start (date);
break;
case GNC_ACCOUNTING_PERIOD_CYEAR:
gnc_gdate_set_year_start (date);
break;
case GNC_ACCOUNTING_PERIOD_CYEAR_PREV:
gnc_gdate_set_prev_year_start (date);
break;
case GNC_ACCOUNTING_PERIOD_FYEAR:
if (fy_end == NULL)
{
PINFO ("Request for fisal year value but no fiscal year end value provided.");
g_date_free (date);
return NULL;
}
gnc_gdate_set_fiscal_year_start (date, fy_end);
break;
case GNC_ACCOUNTING_PERIOD_FYEAR_PREV:
if (fy_end == NULL)
{
PINFO ("Request for fisal year value but no fiscal year end value provided.");
g_date_free (date);
return NULL;
}
gnc_gdate_set_prev_fiscal_year_start (date, fy_end);
break;
}
return date;
}
static time64
gnc_accounting_period_start_time64 (GncAccountingPeriod which,
const GDate *fy_end,
const GDate *contains)
{
GDate *date;
time64 secs;
date = gnc_accounting_period_start_gdate (which, fy_end, contains);
if (!date)
return 0;
secs = gnc_time64_get_day_start_gdate (date);
g_date_free (date);
return secs;
}
GDate *
gnc_accounting_period_end_gdate (GncAccountingPeriod which,
const GDate *fy_end,
const GDate *contains)
{
GDate *date;
if (contains)
{
date = g_date_new_dmy (g_date_get_day (contains),
g_date_get_month (contains),
g_date_get_year (contains));
}
else
{
date = g_date_new ();
gnc_gdate_set_today (date);
}
switch (which)
{
default:
PINFO ("Undefined relative time constant %d", which);
g_date_free (date);
return 0;
case GNC_ACCOUNTING_PERIOD_TODAY:
/* Already have today's date */
break;
case GNC_ACCOUNTING_PERIOD_MONTH:
gnc_gdate_set_month_end (date);
break;
case GNC_ACCOUNTING_PERIOD_MONTH_PREV:
gnc_gdate_set_prev_month_end (date);
break;
case GNC_ACCOUNTING_PERIOD_QUARTER:
gnc_gdate_set_quarter_end (date);
break;
case GNC_ACCOUNTING_PERIOD_QUARTER_PREV:
gnc_gdate_set_prev_quarter_end (date);
break;
case GNC_ACCOUNTING_PERIOD_CYEAR:
gnc_gdate_set_year_end (date);
break;
case GNC_ACCOUNTING_PERIOD_CYEAR_PREV:
gnc_gdate_set_prev_year_end (date);
break;
case GNC_ACCOUNTING_PERIOD_FYEAR:
if (fy_end == NULL)
{
PINFO ("Request for fisal year value but no fiscal year end value provided.");
g_date_free (date);
return 0;
}
gnc_gdate_set_fiscal_year_end (date, fy_end);
break;
case GNC_ACCOUNTING_PERIOD_FYEAR_PREV:
if (fy_end == NULL)
{
PINFO ("Request for fisal year value but no fiscal year end value provided.");
g_date_free (date);
return 0;
}
gnc_gdate_set_prev_fiscal_year_end (date, fy_end);
break;
}
return date;
}
static time64
gnc_accounting_period_end_time64 (GncAccountingPeriod which,
const GDate *fy_end,
const GDate *contains)
{
GDate *date;
time64 secs;
date = gnc_accounting_period_end_gdate (which, fy_end, contains);
if (!date)
return 0;
secs = gnc_time64_get_day_end_gdate (date);
g_date_free (date);
return secs ;
}
/** @} */