LCOV - code coverage report
Current view: top level - libgnucash/engine - SX-book.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 54.8 % 135 74
Test Date: 2026-11-02 18:19:43 Functions: 78.6 % 28 22
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /********************************************************************\
       2              :  * SX-book.c -- scheduled transaction dataset access                *
       3              :  *                                                                  *
       4              :  * This program is free software; you can redistribute it and/or    *
       5              :  * modify it under the terms of the GNU General Public License as   *
       6              :  * published by the Free Software Foundation; either version 2 of   *
       7              :  * the License, or (at your option) any later version.              *
       8              :  *                                                                  *
       9              :  * This program is distributed in the hope that it will be useful,  *
      10              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      11              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      12              :  * GNU General Public License for more details.                     *
      13              :  *                                                                  *
      14              :  * You should have received a copy of the GNU General Public License*
      15              :  * along with this program; if not, contact:                        *
      16              :  *                                                                  *
      17              :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      18              :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      19              :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      20              : \********************************************************************/
      21              : 
      22              : /*
      23              :  * FILE:
      24              :  * SX-book.c
      25              :  *
      26              :  * FUNCTION:
      27              :  * Anchor Scheduled Transaction Info into the book.
      28              :  * See src/doc/books.txt for design overview.
      29              :  *
      30              :  * HISTORY:
      31              :  * Copyright (c) 2003 Linas Vepstas <linas@linas.org>
      32              :  */
      33              : 
      34              : #include <config.h>
      35              : 
      36              : #include <stdlib.h>
      37              : #include <string.h>
      38              : 
      39              : #include <glib.h>
      40              : 
      41              : #include "gnc-engine.h"
      42              : #include "Account.h"
      43              : #include "Split.h"
      44              : #include "SchedXaction.h"
      45              : #include "SX-book.h"
      46              : #include "SX-book-p.h"
      47              : #include "gnc-event.h"
      48              : #include <qofinstance-p.h>
      49              : 
      50              : #undef G_LOG_DOMAIN
      51              : #define G_LOG_DOMAIN "gnc.engine.sx"
      52              : 
      53              : /* XXX this whole file is crufty, it doesn't really use entities
      54              :  * in the most efficient/best way */
      55              : 
      56              : /* ====================================================================== */
      57              : 
      58              : static Account *
      59          769 : gnc_collection_get_template_root( const QofCollection *col )
      60              : {
      61          769 :     return GNC_ACCOUNT(qof_collection_get_data (col));
      62              : }
      63              : 
      64              : Account *
      65          101 : gnc_book_get_template_root( const QofBook *book )
      66              : {
      67              :     QofCollection *col;
      68          101 :     if (!book) return NULL;
      69          101 :     col = qof_book_get_collection (book, GNC_ID_SXTG);
      70          101 :     return gnc_collection_get_template_root (col);
      71              : }
      72              : 
      73              : static void
      74          668 : gnc_collection_set_template_root (QofCollection *col,
      75              :                                   Account *templateRoot)
      76              : {
      77              :     Account *old_root;
      78          668 :     if (!col) return;
      79              : 
      80          668 :     old_root = gnc_collection_get_template_root (col);
      81          668 :     if (old_root == templateRoot) return;
      82              : 
      83          489 :     qof_collection_set_data (col, templateRoot);
      84              : 
      85          489 :     if (old_root)
      86              :     {
      87          182 :         xaccAccountBeginEdit (old_root);
      88          182 :         xaccAccountDestroy (old_root);
      89              :     }
      90              : }
      91              : 
      92              : 
      93              : void
      94          668 : gnc_book_set_template_root (QofBook *book, Account *templateRoot)
      95              : {
      96              :     QofCollection *col;
      97          668 :     if (!book) return;
      98              : 
      99          668 :     if (templateRoot && gnc_account_get_book(templateRoot) != book)
     100              :     {
     101            0 :         g_critical("cannot mix and match books freely!");
     102            0 :         return;
     103              :     }
     104              : 
     105          668 :     col = qof_book_get_collection (book, GNC_ID_SXTG);
     106          668 :     gnc_collection_set_template_root (col, templateRoot);
     107              : }
     108              : 
     109              : 
     110              : /* ====================================================================== */
     111              : /* gncObject function implementation and registration */
     112              : 
     113              : static void
     114          304 : sxtg_book_begin (QofBook *book)
     115              : {
     116              :     Account *root;
     117              : 
     118          304 :     root = xaccMallocAccount(book);
     119          304 :     xaccAccountBeginEdit(root);
     120          304 :     xaccAccountSetType(root, ACCT_TYPE_ROOT);
     121          304 :     xaccAccountSetName(root, "Template Root");
     122          304 :     qof_instance_set_dirty (QOF_INSTANCE (root));
     123          304 :     xaccAccountCommitEdit(root);
     124          304 :     gnc_book_set_template_root (book, root);
     125          304 : }
     126              : 
     127              : static void
     128          179 : sxtg_book_end (QofBook *book)
     129              : {
     130          179 :     gnc_book_set_template_root (book, NULL);
     131          179 : }
     132              : 
     133              : static gboolean
     134            0 : sxtg_is_dirty(const QofCollection *col)
     135              : {
     136              :     Account *root;
     137              :     GList *descendants, *node;
     138            0 :     gboolean dirty = FALSE;
     139              : 
     140            0 :     root = gnc_collection_get_template_root(col);
     141            0 :     descendants = gnc_account_get_descendants(root);
     142            0 :     for (node = descendants; node; node = g_list_next(node))
     143              :     {
     144            0 :         if (qof_instance_is_dirty(QOF_INSTANCE(node->data)))
     145              :         {
     146            0 :             dirty = TRUE;
     147            0 :             break;
     148              :         }
     149              :     }
     150            0 :     g_list_free(descendants);
     151              : 
     152            0 :     return dirty;
     153              : }
     154              : 
     155              : /* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
     156              : extern void qof_instance_mark_clean (QofInstance *);
     157              : 
     158              : static void
     159            0 : sxtg_mark_clean(QofCollection *col)
     160              : {
     161              :     Account *root;
     162              :     GList *descendants;
     163              : 
     164            0 :     root = gnc_collection_get_template_root(col);
     165            0 :     qof_collection_mark_clean(col);
     166              : 
     167            0 :     descendants = gnc_account_get_descendants(root);
     168            0 :     g_list_foreach(descendants, (GFunc)qof_instance_mark_clean, NULL);
     169            0 :     g_list_free(descendants);
     170            0 : }
     171              : 
     172              : #ifdef _MSC_VER
     173              : /* MSVC compiler doesn't have C99 "designated initializers"
     174              :  * so we wrap them in a macro that is empty on MSVC. */
     175              : # define DI(x) /* */
     176              : #else
     177              : # define DI(x) x
     178              : #endif
     179              : static QofObject sxtg_object_def =
     180              : {
     181              :     DI(.interface_version = ) QOF_OBJECT_VERSION,
     182              :     DI(.e_type            = ) GNC_ID_SXTG,
     183              :     DI(.type_label        = ) "Scheduled Transaction Group",
     184              :     DI(.create            = ) NULL,
     185              :     DI(.book_begin        = ) sxtg_book_begin,
     186              :     DI(.book_end          = ) sxtg_book_end,
     187              :     DI(.is_dirty          = ) sxtg_is_dirty,
     188              :     DI(.mark_clean        = ) sxtg_mark_clean,
     189              :     DI(.foreach           = ) NULL,
     190              :     DI(.printable         = ) NULL,
     191              : };
     192              : 
     193              : /* ====================================================================== */
     194              : 
     195              : SchedXactions*
     196           83 : gnc_collection_get_schedxactions(const QofCollection *col)
     197              : {
     198           83 :     auto rtn = GNC_SCHEDXACTIONS (qof_collection_get_data(col));
     199              :     // @@assert(rtn != null);
     200           83 :     return rtn;
     201              : }
     202              : 
     203              : SchedXactions*
     204           83 : gnc_book_get_schedxactions(QofBook *book)
     205              : {
     206              :     QofCollection *col;
     207           83 :     col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
     208           83 :     return gnc_collection_get_schedxactions(col);
     209              : }
     210              : 
     211              : void
     212           24 : gnc_sxes_add_sx(SchedXactions *sxes, SchedXaction *sx)
     213              : {
     214           24 :     if (g_list_find(sxes->sx_list, sx) != NULL)
     215            0 :         return;
     216           24 :     sxes->sx_list = g_list_append(sxes->sx_list, sx);
     217           24 :     qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_ADDED, (gpointer)sx);
     218              : }
     219              : 
     220              : void
     221           16 : gnc_sxes_del_sx(SchedXactions *sxes, SchedXaction *sx)
     222              : {
     223              :     GList *to_remove;
     224           16 :     to_remove = g_list_find(sxes->sx_list, sx);
     225           16 :     if (to_remove == NULL)
     226            0 :         return;
     227           16 :     sxes->sx_list = g_list_delete_link(sxes->sx_list, to_remove);
     228           16 :     qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_REMOVED, (gpointer)sx);
     229              : }
     230              : 
     231              : /* ====================================================================== */
     232              : /* SX-trans stuff */
     233              : 
     234              : /* GObject initialization */
     235         1399 : QOF_GOBJECT_IMPL(gnc_schedxactions, SchedXactions, QOF_TYPE_INSTANCE)
     236              : 
     237              : static void
     238          304 : gnc_schedxactions_init(SchedXactions* sxs)
     239              : {
     240          304 : }
     241              : 
     242              : static void
     243          179 : gnc_schedxactions_dispose_real (GObject *sxsp)
     244              : {
     245          179 : }
     246              : 
     247              : static void
     248          179 : gnc_schedxactions_finalize_real(GObject* sxsp)
     249              : {
     250          179 : }
     251              : 
     252              : static void
     253            0 : mark_sx_clean(gpointer data, gpointer user_data)
     254              : {
     255            0 :     SchedXaction *sx = (SchedXaction *) data;
     256            0 :     qof_instance_mark_clean (QOF_INSTANCE(sx));
     257            0 : }
     258              : 
     259              : static void
     260          304 : book_sxes_setup(QofBook *book)
     261              : {
     262              :     QofCollection *col;
     263              : 
     264          304 :     col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
     265          304 :     auto sxes = GNC_SCHEDXACTIONS (g_object_new (GNC_TYPE_SCHEDXACTIONS, NULL));
     266          304 :     g_assert(sxes);
     267          304 :     qof_instance_init_data(&sxes->inst, GNC_ID_SXES, book);
     268          304 :     sxes->sx_list = NULL;
     269          304 :     sxes->sx_notsaved = TRUE;
     270          304 :     qof_collection_set_data(col, sxes);
     271          304 : }
     272              : 
     273              : static void
     274          179 : book_sxes_end(QofBook* book)
     275              : {
     276              :     QofCollection *col;
     277              : 
     278          179 :     col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
     279          179 :     auto sxes = GNC_SCHEDXACTIONS (qof_collection_get_data(col));
     280          179 :     if (sxes != NULL)
     281              :     {
     282          179 :         g_list_free(sxes->sx_list);
     283          179 :         g_object_unref(sxes);
     284          179 :         qof_collection_set_data(col, NULL);
     285              :     }
     286          179 : }
     287              : 
     288              : static void
     289            0 : book_sxns_mark_saved(QofCollection *col)
     290              : {
     291              :     SchedXactions *sxl;
     292            0 :     sxl = gnc_collection_get_schedxactions(col);
     293            0 :     if (!sxl)
     294            0 :         return;
     295            0 :     sxl->sx_notsaved = FALSE;
     296            0 :     g_list_foreach(sxl->sx_list,
     297              :                    mark_sx_clean,
     298              :                    NULL);
     299              : }
     300              : 
     301              : static gboolean
     302            0 : book_sxlist_notsaved(const QofCollection *col)
     303              : {
     304              :     GList *sxlist;
     305              :     SchedXactions *sxl;
     306              : 
     307            0 :     sxl = gnc_collection_get_schedxactions(col);
     308            0 :     if (!sxl) return FALSE;
     309            0 :     if (sxl->sx_notsaved) return TRUE;
     310              : 
     311            0 :     for (sxlist = sxl->sx_list;
     312            0 :             sxlist != NULL;
     313            0 :             sxlist = g_list_next(sxlist))
     314              :     {
     315              :         SchedXaction *sx;
     316            0 :         sx = (SchedXaction *) (sxlist->data);
     317            0 :         if (xaccSchedXactionIsDirty( sx ))
     318            0 :             return TRUE;
     319              :     }
     320              : 
     321            0 :     return FALSE;
     322              : }
     323              : 
     324              : static QofObject sxes_object_def =
     325              : {
     326              :     DI(.interface_version = ) QOF_OBJECT_VERSION,
     327              :     DI(.e_type            = ) GNC_ID_SXES,
     328              :     DI(.type_label        = ) "Scheduled Transactions List",
     329              :     DI(.create            = ) NULL,
     330              :     DI(.book_begin        = ) book_sxes_setup,
     331              :     DI(.book_end          = ) book_sxes_end,
     332              :     DI(.is_dirty          = ) book_sxlist_notsaved,
     333              :     DI(.mark_clean        = ) book_sxns_mark_saved,
     334              :     DI(.foreach           = ) NULL,
     335              :     DI(.printable         = ) NULL,
     336              :     DI(.version_cmp       = ) NULL
     337              : };
     338              : 
     339              : static QofObject sxtt_object_def =
     340              : {
     341              :     DI(.interface_version = ) QOF_OBJECT_VERSION,
     342              :     DI(.e_type            = ) GNC_ID_SXTT,
     343              :     DI(.type_label        = ) "Scheduled Transaction Templates",
     344              :     DI(.create            = ) NULL,
     345              :     DI(.book_begin        = ) NULL,
     346              :     DI(.book_end          = ) NULL,
     347              :     DI(.is_dirty          = ) NULL,
     348              :     DI(.mark_clean        = ) NULL,
     349              :     DI(.foreach           = ) NULL,
     350              :     DI(.printable         = ) NULL,
     351              :     DI(.version_cmp       = ) NULL,
     352              : };
     353              : 
     354              : gboolean
     355           83 : gnc_sxtt_register (void)
     356              : {
     357           83 :     if (!qof_object_register(&sxes_object_def))
     358            0 :         return FALSE;
     359           83 :     if (!qof_object_register(&sxtg_object_def))
     360            0 :         return FALSE;
     361           83 :     return qof_object_register(&sxtt_object_def);
     362              : }
     363              : 
     364              : GList*
     365            0 : gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
     366              : {
     367            0 :     GList *rtn = NULL;
     368            0 :     const GncGUID *acct_guid = qof_entity_get_guid(QOF_INSTANCE(acct));
     369              :     GList *sx_list;
     370            0 :     SchedXactions *sxactions = gnc_book_get_schedxactions(book);
     371            0 :     g_return_val_if_fail( sxactions != NULL, rtn);
     372            0 :     for (sx_list = sxactions->sx_list; sx_list != NULL; sx_list = sx_list->next)
     373              :     {
     374            0 :         SchedXaction *sx = (SchedXaction*)sx_list->data;
     375            0 :         GList *splits = xaccSchedXactionGetSplits(sx);
     376            0 :         for (GList *node = splits; node; node = node->next)
     377              :         {
     378            0 :             Split *s = (Split*)node->data;
     379            0 :             GncGUID *guid = NULL;
     380            0 :             qof_instance_get (QOF_INSTANCE (s), "sx-account", &guid, NULL);
     381            0 :             if (guid_equal(acct_guid, guid))
     382            0 :                 rtn = g_list_prepend (rtn, sx);
     383              : 
     384            0 :             guid_free (guid);
     385              :         }
     386            0 :         g_list_free (splits);
     387              :     }
     388            0 :     return g_list_reverse (rtn);
     389              : }
     390              : 
     391              : /* ========================== END OF FILE =============================== */
        

Generated by: LCOV version 2.0-1