LCOV - code coverage report
Current view: top level - libgnucash/engine - gnc-accounting-period.c (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 42.3 % 137 58
Test Date: 2026-11-02 18:19:43 Functions: 100.0 % 9 9
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * gnc-accounting-period.c --
       3              :  *
       4              :  * Copyright (c) 2005 David Hampton <hampton@employees.org>
       5              :  * All rights reserved.
       6              :  *
       7              :  * GnuCash is free software; you can redistribute it and/or modify
       8              :  * it under the terms of the GNU Library General Public License as
       9              :  * published by the Free Software Foundation; either version 2 of
      10              :  * the License, or (at your option) any later version.
      11              :  *
      12              :  * Gnucash is distributed in the hope that it will be useful,
      13              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              :  * Library General Public License for more details.
      16              :  *
      17              :  * You should have received a copy of the GNU General Public License
      18              :  * along with this program; if not, contact:
      19              :  *
      20              :  * Free Software Foundation           Voice:  +1-617-542-5942
      21              :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
      22              :  * Boston, MA  02110-1301,  USA       gnu@gnu.org
      23              :  */
      24              : 
      25              : /** @addtogroup GUI
      26              :     @{ */
      27              : /** @file gnc-accounting-period.c
      28              :     @brief General utilities for dealing with accounting periods.
      29              :     @author David Hampton <hampton@employees.org>
      30              : 
      31              :     These are general utility functions for specifying an accounting
      32              :     period and converting it to a value usable by the gnucash engine.
      33              :     The choice of src/app-utils is arbitrary as these utilities don't
      34              :     fit well anywhere else.  They are at a higher level than a GDate,
      35              :     so they don't fit in src/core-utils/gnc-gdate-utils.c.  They don't
      36              :     operate on engine data structures, so they don't belong in
      37              :     src/engine/Period.c.  Putting them into src/engine/gnc-date.c
      38              :     would be the best place for them, but then that creates a new
      39              :     dependency from the src/engine directory to the src/core-utils
      40              :     directory that doesn't currently exist.  Since that might be a
      41              :     problem for CashUtils, the app-file directory was chosen.
      42              : */
      43              : 
      44              : #include <config.h>
      45              : #include <string.h>
      46              : #include "gnc-accounting-period.h"
      47              : #include "gnc-date.h"
      48              : #include "gnc-prefs.h"
      49              : #include "qof.h"
      50              : #include "gnc-session.h"
      51              : 
      52              : static const QofLogModule log_module = G_LOG_DOMAIN;
      53              : static time64 gnc_accounting_period_start_time64 (GncAccountingPeriod which,
      54              :                                                   const GDate *fy_end,
      55              :                                                   const GDate *contains);
      56              : static time64 gnc_accounting_period_end_time64 (GncAccountingPeriod which,
      57              :                                                 const GDate *fy_end,
      58              :                                                 const GDate *contains);
      59              : 
      60              : static time64
      61          226 : lookup_start_date_option (GDate *fy_end)
      62              : {
      63              :     time64 time;
      64              :     int which;
      65              : 
      66          226 :     if (gnc_prefs_get_bool (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_CHOICE_ABS))
      67           24 :         time = gnc_time64_get_day_start (gnc_prefs_get_int64
      68              :                                         (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_DATE));
      69              :     else
      70              :     {
      71          202 :         which = gnc_prefs_get_int (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_PERIOD);
      72          202 :         time = gnc_accounting_period_start_time64 (which, fy_end, NULL);
      73              :     }
      74              :     /* we will need the balance of the last transaction before the start
      75              :        date, so subtract 1 from start date */
      76              :     /* CAS: we don't actually do what this comment says.  I think that's
      77              :        because a bug in the engine has been fixed. */
      78          226 :     return time;
      79              : }
      80              : 
      81              : static time64
      82           41 : lookup_end_date_option (GDate *fy_end)
      83              : {
      84              :     time64 time;
      85              :     int which;
      86              : 
      87           41 :     if (gnc_prefs_get_bool (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_CHOICE_ABS))
      88            0 :         time = gnc_time64_get_day_end (gnc_prefs_get_int64
      89              :                                       (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_DATE));
      90              :     else
      91              :     {
      92           41 :         which = gnc_prefs_get_int (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_PERIOD);
      93           41 :         time = gnc_accounting_period_end_time64 (which, fy_end, NULL);
      94              :     }
      95           41 :     if (time == 0)
      96            0 :         time = -1;
      97           41 :     return time;
      98              : }
      99              : 
     100              : static GDate *
     101          267 : get_fy_end (void)
     102              : {
     103              :     QofBook *book;
     104          267 :     GDate *date = NULL;
     105              : 
     106          267 :     book = qof_session_get_book(gnc_get_current_session());
     107          267 :     qof_instance_get (QOF_INSTANCE (book), "fy-end", &date, NULL);
     108          267 :     return date;
     109              : }
     110              : 
     111              : time64
     112          226 : gnc_accounting_period_fiscal_start (void)
     113              : {
     114              :     time64 t;
     115          226 :     GDate *fy_end = get_fy_end();
     116          226 :     t = lookup_start_date_option (fy_end);
     117          226 :     if (fy_end)
     118            0 :         g_date_free (fy_end);
     119          226 :     return t;
     120              : }
     121              : 
     122              : time64
     123           41 : gnc_accounting_period_fiscal_end (void)
     124              : {
     125              :     time64 t;
     126           41 :     GDate *fy_end = get_fy_end();
     127              : 
     128           41 :     t = lookup_end_date_option (fy_end);
     129           41 :     if (fy_end)
     130            0 :         g_date_free (fy_end);
     131           41 :     return t;
     132              : }
     133              : 
     134              : GDate *
     135          202 : gnc_accounting_period_start_gdate (GncAccountingPeriod which,
     136              :                                    const GDate *fy_end,
     137              :                                    const GDate *contains)
     138              : {
     139              :     GDate *date;
     140              : 
     141          202 :     if (contains)
     142              :     {
     143            0 :         date = g_date_new_dmy (g_date_get_day (contains),
     144              :                                g_date_get_month (contains),
     145            0 :                                g_date_get_year (contains));
     146              :     }
     147              :     else
     148              :     {
     149          202 :         date = g_date_new ();
     150          202 :         gnc_gdate_set_today (date);
     151              :     }
     152              : 
     153          202 :     switch (which)
     154              :     {
     155            0 :     default:
     156            0 :         PINFO ("Undefined relative time constant %d", which);
     157            0 :         g_date_free (date);
     158            0 :         return NULL;
     159              : 
     160          178 :     case GNC_ACCOUNTING_PERIOD_TODAY:
     161              :         /* Already have today's date */
     162          178 :         break;
     163              : 
     164            0 :     case GNC_ACCOUNTING_PERIOD_MONTH:
     165            0 :         gnc_gdate_set_month_start (date);
     166            0 :         break;
     167              : 
     168            0 :     case GNC_ACCOUNTING_PERIOD_MONTH_PREV:
     169            0 :         gnc_gdate_set_prev_month_start (date);
     170            0 :         break;
     171              : 
     172            0 :     case GNC_ACCOUNTING_PERIOD_QUARTER:
     173            0 :         gnc_gdate_set_quarter_start (date);
     174            0 :         break;
     175              : 
     176            0 :     case GNC_ACCOUNTING_PERIOD_QUARTER_PREV:
     177            0 :         gnc_gdate_set_prev_quarter_start (date);
     178            0 :         break;
     179              : 
     180           24 :     case GNC_ACCOUNTING_PERIOD_CYEAR:
     181           24 :         gnc_gdate_set_year_start (date);
     182           24 :         break;
     183              : 
     184            0 :     case GNC_ACCOUNTING_PERIOD_CYEAR_PREV:
     185            0 :         gnc_gdate_set_prev_year_start (date);
     186            0 :         break;
     187              : 
     188            0 :     case GNC_ACCOUNTING_PERIOD_FYEAR:
     189            0 :         if (fy_end == NULL)
     190              :         {
     191            0 :             PINFO ("Request for fiscal year value but no fiscal year end value provided.");
     192            0 :             g_date_free (date);
     193            0 :             return NULL;
     194              :         }
     195            0 :         gnc_gdate_set_fiscal_year_start (date, fy_end);
     196            0 :         break;
     197              : 
     198            0 :     case GNC_ACCOUNTING_PERIOD_FYEAR_PREV:
     199            0 :         if (fy_end == NULL)
     200              :         {
     201            0 :             PINFO ("Request for fiscal year value but no fiscal year end value provided.");
     202            0 :             g_date_free (date);
     203            0 :             return NULL;
     204              :         }
     205            0 :         gnc_gdate_set_prev_fiscal_year_start (date, fy_end);
     206            0 :         break;
     207              :     }
     208          202 :     return date;
     209              : }
     210              : 
     211              : static time64
     212          202 : gnc_accounting_period_start_time64 (GncAccountingPeriod which,
     213              :                                     const GDate *fy_end,
     214              :                                     const GDate *contains)
     215              : {
     216              :     GDate *date;
     217              :     time64 secs;
     218              : 
     219          202 :     date = gnc_accounting_period_start_gdate (which, fy_end, contains);
     220          202 :     if (!date)
     221            0 :         return 0;
     222              : 
     223          202 :     secs = gnc_time64_get_day_start_gdate (date);
     224          202 :     g_date_free (date);
     225          202 :     return secs;
     226              : }
     227              : 
     228              : GDate *
     229           41 : gnc_accounting_period_end_gdate (GncAccountingPeriod which,
     230              :                                  const GDate *fy_end,
     231              :                                  const GDate *contains)
     232              : {
     233              :     GDate *date;
     234              : 
     235           41 :     if (contains)
     236              :     {
     237            0 :         date = g_date_new_dmy (g_date_get_day (contains),
     238              :                                g_date_get_month (contains),
     239            0 :                                g_date_get_year (contains));
     240              :     }
     241              :     else
     242              :     {
     243           41 :         date = g_date_new ();
     244           41 :         gnc_gdate_set_today (date);
     245              :     }
     246              : 
     247           41 :     switch (which)
     248              :     {
     249            0 :     default:
     250            0 :         PINFO ("Undefined relative time constant %d", which);
     251            0 :         g_date_free (date);
     252            0 :         return 0;
     253              : 
     254           41 :     case GNC_ACCOUNTING_PERIOD_TODAY:
     255              :         /* Already have today's date */
     256           41 :         break;
     257              : 
     258            0 :     case GNC_ACCOUNTING_PERIOD_MONTH:
     259            0 :         gnc_gdate_set_month_end (date);
     260            0 :         break;
     261              : 
     262            0 :     case GNC_ACCOUNTING_PERIOD_MONTH_PREV:
     263            0 :         gnc_gdate_set_prev_month_end (date);
     264            0 :         break;
     265              : 
     266            0 :     case GNC_ACCOUNTING_PERIOD_QUARTER:
     267            0 :         gnc_gdate_set_quarter_end (date);
     268            0 :         break;
     269              : 
     270            0 :     case GNC_ACCOUNTING_PERIOD_QUARTER_PREV:
     271            0 :         gnc_gdate_set_prev_quarter_end (date);
     272            0 :         break;
     273              : 
     274            0 :     case GNC_ACCOUNTING_PERIOD_CYEAR:
     275            0 :         gnc_gdate_set_year_end (date);
     276            0 :         break;
     277              : 
     278            0 :     case GNC_ACCOUNTING_PERIOD_CYEAR_PREV:
     279            0 :         gnc_gdate_set_prev_year_end (date);
     280            0 :         break;
     281              : 
     282            0 :     case GNC_ACCOUNTING_PERIOD_FYEAR:
     283            0 :         if (fy_end == NULL)
     284              :         {
     285            0 :             PINFO ("Request for fisal year value but no fiscal year end value provided.");
     286            0 :             g_date_free (date);
     287            0 :             return 0;
     288              :         }
     289            0 :         gnc_gdate_set_fiscal_year_end (date, fy_end);
     290            0 :         break;
     291              : 
     292            0 :     case GNC_ACCOUNTING_PERIOD_FYEAR_PREV:
     293            0 :         if (fy_end == NULL)
     294              :         {
     295            0 :             PINFO ("Request for fisal year value but no fiscal year end value provided.");
     296            0 :             g_date_free (date);
     297            0 :             return 0;
     298              :         }
     299            0 :         gnc_gdate_set_prev_fiscal_year_end (date, fy_end);
     300            0 :         break;
     301              :     }
     302              : 
     303           41 :     return date;
     304              : }
     305              : 
     306              : static time64
     307           41 : gnc_accounting_period_end_time64 (GncAccountingPeriod which,
     308              :                                   const GDate *fy_end,
     309              :                                   const GDate *contains)
     310              : {
     311              :     GDate *date;
     312              :     time64 secs;
     313              : 
     314           41 :     date = gnc_accounting_period_end_gdate (which, fy_end, contains);
     315           41 :     if (!date)
     316            0 :         return 0;
     317              : 
     318           41 :     secs = gnc_time64_get_day_end_gdate (date);
     319           41 :     g_date_free (date);
     320           41 :     return secs ;
     321              : }
     322              : 
     323              : /** @} */
        

Generated by: LCOV version 2.0-1