GnuCash c935c2f+
Loading...
Searching...
No Matches
SX-book.cpp
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
58static Account *
59gnc_collection_get_template_root( const QofCollection *col )
60{
61 return GNC_ACCOUNT(qof_collection_get_data (col));
62}
63
64Account *
66{
67 QofCollection *col;
68 if (!book) return NULL;
69 col = qof_book_get_collection (book, GNC_ID_SXTG);
70 return gnc_collection_get_template_root (col);
71}
72
73static void
74gnc_collection_set_template_root (QofCollection *col,
75 Account *templateRoot)
76{
77 Account *old_root;
78 if (!col) return;
79
80 old_root = gnc_collection_get_template_root (col);
81 if (old_root == templateRoot) return;
82
83 qof_collection_set_data (col, templateRoot);
84
85 if (old_root)
86 {
87 xaccAccountBeginEdit (old_root);
88 xaccAccountDestroy (old_root);
89 }
90}
91
92
93void
94gnc_book_set_template_root (QofBook *book, Account *templateRoot)
95{
96 QofCollection *col;
97 if (!book) return;
98
99 if (templateRoot && gnc_account_get_book(templateRoot) != book)
100 {
101 g_critical("cannot mix and match books freely!");
102 return;
103 }
104
105 col = qof_book_get_collection (book, GNC_ID_SXTG);
106 gnc_collection_set_template_root (col, templateRoot);
107}
108
109
110/* ====================================================================== */
111/* gncObject function implementation and registration */
112
113static void
114sxtg_book_begin (QofBook *book)
115{
116 Account *root;
117
118 root = xaccMallocAccount(book);
120 xaccAccountSetType(root, ACCT_TYPE_ROOT);
121 xaccAccountSetName(root, "Template Root");
122 qof_instance_set_dirty (QOF_INSTANCE (root));
124 gnc_book_set_template_root (book, root);
125}
126
127static void
128sxtg_book_end (QofBook *book)
129{
130 gnc_book_set_template_root (book, NULL);
131}
132
133static gboolean
134sxtg_is_dirty(const QofCollection *col)
135{
136 Account *root;
137 GList *descendants, *node;
138 gboolean dirty = FALSE;
139
140 root = gnc_collection_get_template_root(col);
141 descendants = gnc_account_get_descendants(root);
142 for (node = descendants; node; node = g_list_next(node))
143 {
144 if (qof_instance_is_dirty(QOF_INSTANCE(node->data)))
145 {
146 dirty = TRUE;
147 break;
148 }
149 }
150 g_list_free(descendants);
151
152 return dirty;
153}
154
155/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
156extern void qof_instance_mark_clean (QofInstance *);
157
158static void
159sxtg_mark_clean(QofCollection *col)
160{
161 Account *root;
162 GList *descendants;
163
164 root = gnc_collection_get_template_root(col);
166
167 descendants = gnc_account_get_descendants(root);
168 g_list_foreach(descendants, (GFunc)qof_instance_mark_clean, NULL);
169 g_list_free(descendants);
170}
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
179static 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
195SchedXactions*
196gnc_collection_get_schedxactions(const QofCollection *col)
197{
198 auto rtn = GNC_SCHEDXACTIONS (qof_collection_get_data(col));
199 // @@assert(rtn != null);
200 return rtn;
201}
202
203SchedXactions*
204gnc_book_get_schedxactions(QofBook *book)
205{
206 QofCollection *col;
207 col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
208 return gnc_collection_get_schedxactions(col);
209}
210
211void
212gnc_sxes_add_sx(SchedXactions *sxes, SchedXaction *sx)
213{
214 if (g_list_find(sxes->sx_list, sx) != NULL)
215 return;
216 sxes->sx_list = g_list_append(sxes->sx_list, sx);
217 qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_ADDED, (gpointer)sx);
218}
219
220void
221gnc_sxes_del_sx(SchedXactions *sxes, SchedXaction *sx)
222{
223 GList *to_remove;
224 to_remove = g_list_find(sxes->sx_list, sx);
225 if (to_remove == NULL)
226 return;
227 sxes->sx_list = g_list_delete_link(sxes->sx_list, to_remove);
228 qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_REMOVED, (gpointer)sx);
229}
230
231/* ====================================================================== */
232/* SX-trans stuff */
233
234/* GObject initialization */
235QOF_GOBJECT_IMPL(gnc_schedxactions, SchedXactions, QOF_TYPE_INSTANCE)
236
237static void
238gnc_schedxactions_init(SchedXactions* sxs)
239{
240}
241
242static void
243gnc_schedxactions_dispose_real (GObject *sxsp)
244{
245}
246
247static void
248gnc_schedxactions_finalize_real(GObject* sxsp)
249{
250}
251
252static void
253mark_sx_clean(gpointer data, gpointer user_data)
254{
255 SchedXaction *sx = (SchedXaction *) data;
256 qof_instance_mark_clean (QOF_INSTANCE(sx));
257}
258
259static void
260book_sxes_setup(QofBook *book)
261{
262 QofCollection *col;
263
264 col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
265 auto sxes = GNC_SCHEDXACTIONS (g_object_new (GNC_TYPE_SCHEDXACTIONS, NULL));
266 g_assert(sxes);
267 qof_instance_init_data(&sxes->inst, GNC_ID_SXES, book);
268 sxes->sx_list = NULL;
269 sxes->sx_notsaved = TRUE;
270 qof_collection_set_data(col, sxes);
271}
272
273static void
274book_sxes_end(QofBook* book)
275{
276 QofCollection *col;
277
278 col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
279 auto sxes = GNC_SCHEDXACTIONS (qof_collection_get_data(col));
280 if (sxes != NULL)
281 {
282 g_list_free(sxes->sx_list);
283 g_object_unref(sxes);
284 qof_collection_set_data(col, NULL);
285 }
286}
287
288static void
289book_sxns_mark_saved(QofCollection *col)
290{
291 SchedXactions *sxl;
292 sxl = gnc_collection_get_schedxactions(col);
293 if (!sxl)
294 return;
295 sxl->sx_notsaved = FALSE;
296 g_list_foreach(sxl->sx_list,
297 mark_sx_clean,
298 NULL);
299}
300
301static gboolean
302book_sxlist_notsaved(const QofCollection *col)
303{
304 GList *sxlist;
305 SchedXactions *sxl;
306
307 sxl = gnc_collection_get_schedxactions(col);
308 if (!sxl) return FALSE;
309 if (sxl->sx_notsaved) return TRUE;
310
311 for (sxlist = sxl->sx_list;
312 sxlist != NULL;
313 sxlist = g_list_next(sxlist))
314 {
315 SchedXaction *sx;
316 sx = (SchedXaction *) (sxlist->data);
317 if (xaccSchedXactionIsDirty( sx ))
318 return TRUE;
319 }
320
321 return FALSE;
322}
323
324static 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
339static 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
354gboolean
355gnc_sxtt_register (void)
356{
357 if (!qof_object_register(&sxes_object_def))
358 return FALSE;
359 if (!qof_object_register(&sxtg_object_def))
360 return FALSE;
361 return qof_object_register(&sxtt_object_def);
362}
363
364GList*
366{
367 GList *rtn = NULL;
368 const GncGUID *acct_guid = qof_entity_get_guid(QOF_INSTANCE(acct));
369 GList *sx_list;
370 SchedXactions *sxactions = gnc_book_get_schedxactions(book);
371 g_return_val_if_fail( sxactions != NULL, rtn);
372 for (sx_list = sxactions->sx_list; sx_list != NULL; sx_list = sx_list->next)
373 {
374 SchedXaction *sx = (SchedXaction*)sx_list->data;
375 GList *splits = xaccSchedXactionGetSplits(sx);
376 for (GList *node = splits; node; node = node->next)
377 {
378 Split *s = (Split*)node->data;
379 GncGUID *guid = NULL;
380 qof_instance_get (QOF_INSTANCE (s), "sx-account", &guid, NULL);
381 if (guid_equal(acct_guid, guid))
382 rtn = g_list_prepend (rtn, sx);
383
384 guid_free (guid);
385 }
386 g_list_free (splits);
387 }
388 return g_list_reverse (rtn);
389}
390
391/* ========================== END OF FILE =============================== */
Account handling public routines.
Anchor Scheduled Transaction info in a book.
Scheduled Transactions public handling routines.
API for Transactions and Splits (journal entries)
All type declarations for the whole Gnucash engine.
Additional event handling code.
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition Account.cpp:1516
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition Account.cpp:1475
void xaccAccountSetName(Account *acc, const char *str)
Set the account's name.
Definition Account.cpp:2458
GList * gnc_account_get_descendants(const Account *account)
This routine returns a flat list of all of the accounts that are descendants of the specified account...
Definition Account.cpp:3044
void xaccAccountDestroy(Account *acc)
The xaccAccountDestroy() routine can be used to get rid of an account.
Definition Account.cpp:1590
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Set the account's type.
Definition Account.cpp:2437
Account * xaccMallocAccount(QofBook *book)
Constructor.
Definition Account.cpp:1270
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
Definition qofbook.cpp:521
gpointer qof_collection_get_data(const QofCollection *col)
Store and retrieve arbitrary object-defined data.
Definition qofid.cpp:266
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition qofevent.cpp:231
#define GNC_EVENT_ITEM_ADDED
These events are used when a split is added to an account.
Definition gnc-event.h:45
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
Definition guid.cpp:237
#define qof_instance_is_dirty
Return value of is_dirty flag.
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
const GncGUID * qof_entity_get_guid(gconstpointer ent)
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
Definition qofid.cpp:238
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
Definition qofobject.h:63
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
#define xaccSchedXactionIsDirty(X)
GList * gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
Definition SX-book.cpp:365
Account * gnc_book_get_template_root(const QofBook *book)
Returns the template group from the book.
Definition SX-book.cpp:65
STRUCTS.
The type used to store guids in C.
Definition guid.h:75
QofBook reference.
Definition qofbook-p.hpp:47