GnuCash  5.6-150-g038405b370+
SchedXaction.cpp
1 /********************************************************************\
2  * SchedXaction.c -- Scheduled Transaction implementation. *
3  * Copyright (C) 2001,2007 Joshua Sled <jsled@asynchronous.org> *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22 \********************************************************************/
23 
24 #include <config.h>
25 
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <string.h>
29 #include <stdint.h>
30 
31 #include "qof.h"
32 
33 #include "Account.h"
34 #include "Account.hpp"
35 #include "SX-book.h"
36 #include "SX-book-p.h"
37 #include "SX-ttinfo.hpp"
38 #include "SchedXaction.h"
39 #include "SchedXaction.hpp"
40 #include "Transaction.h"
41 #include "gnc-engine.h"
42 #include "engine-helpers.h"
43 #include "qofinstance-p.h"
44 
45 #include <unordered_set>
46 
47 #undef G_LOG_DOMAIN
48 #define G_LOG_DOMAIN "gnc.engine.sx"
49 
50 enum
51 {
52  PROP_0,
53  PROP_NAME, /* Table */
54  PROP_ENABLED, /* Table */
55  PROP_START_DATE, /* Table */
56  PROP_END_DATE, /* Table */
57  PROP_LAST_OCCURANCE_DATE, /* Table */
58  PROP_NUM_OCCURANCE, /* Table */
59  PROP_REM_OCCURANCE, /* Table */
60  PROP_AUTO_CREATE, /* Table */
61  PROP_AUTO_CREATE_NOTIFY, /* Table */
62  PROP_ADVANCE_CREATION_DAYS, /* Table */
63  PROP_ADVANCE_REMINDER_DAYS, /* Table */
64  PROP_INSTANCE_COUNT, /* Table */
65  PROP_TEMPLATE_ACCOUNT /* Table */
66 };
67 
68 /* GObject initialization */
69 G_DEFINE_TYPE(SchedXaction, gnc_schedxaction, QOF_TYPE_INSTANCE)
70 
71 static void
72 gnc_schedxaction_init(SchedXaction* sx)
73 {
74  sx->schedule = NULL;
75 
76  g_date_clear( &sx->last_date, 1 );
77  g_date_clear( &sx->start_date, 1 );
78  g_date_clear( &sx->end_date, 1 );
79 
80  sx->enabled = 1;
81  sx->num_occurances_total = 0;
82  sx->autoCreateOption = FALSE;
83  sx->autoCreateNotify = FALSE;
84  sx->advanceCreateDays = 0;
85  sx->advanceRemindDays = 0;
86  sx->instance_num = 0;
87  sx->deferredList = NULL;
88 }
89 
90 static void
91 gnc_schedxaction_dispose(GObject *sxp)
92 {
93  G_OBJECT_CLASS(gnc_schedxaction_parent_class)->dispose(sxp);
94 }
95 
96 static void
97 gnc_schedxaction_finalize(GObject* sxp)
98 {
99  G_OBJECT_CLASS(gnc_schedxaction_parent_class)->finalize(sxp);
100 }
101 
102 /* Note that g_value_set_object() refs the object, as does
103  * g_object_get(). But g_object_get() only unrefs once when it disgorges
104  * the object, leaving an unbalanced ref, which leaks. So instead of
105  * using g_value_set_object(), use g_value_take_object() which doesn't
106  * ref the object when used in get_property().
107  */
108 static void
109 gnc_schedxaction_get_property (GObject *object,
110  guint prop_id,
111  GValue *value,
112  GParamSpec *pspec)
113 {
114  SchedXaction *sx;
115 
116  g_return_if_fail(GNC_IS_SCHEDXACTION(object));
117 
118  sx = GNC_SCHEDXACTION(object);
119  switch (prop_id)
120  {
121  case PROP_NAME:
122  g_value_set_string(value, sx->name);
123  break;
124  case PROP_ENABLED:
125  g_value_set_boolean(value, sx->enabled);
126  break;
127  case PROP_NUM_OCCURANCE:
128  g_value_set_int(value, sx->num_occurances_total);
129  break;
130  case PROP_REM_OCCURANCE:
131  g_value_set_int(value, sx->num_occurances_remain);
132  break;
133  case PROP_AUTO_CREATE:
134  g_value_set_boolean(value, sx->autoCreateOption);
135  break;
136  case PROP_AUTO_CREATE_NOTIFY:
137  g_value_set_boolean(value, sx->autoCreateNotify);
138  break;
139  case PROP_ADVANCE_CREATION_DAYS:
140  g_value_set_int(value, sx->advanceCreateDays);
141  break;
142  case PROP_ADVANCE_REMINDER_DAYS:
143  g_value_set_int(value, sx->advanceRemindDays);
144  break;
145  case PROP_START_DATE:
146  g_value_set_boxed(value, &sx->start_date);
147  break;
148  case PROP_END_DATE:
149  /* g_value_set_boxed raises a critical error if sx->end_date
150  * is invalid */
151  if (g_date_valid (&sx->end_date))
152  g_value_set_boxed(value, &sx->end_date);
153  break;
154  case PROP_LAST_OCCURANCE_DATE:
155  /* g_value_set_boxed raises a critical error if sx->last_date
156  * is invalid */
157  if (g_date_valid (&sx->last_date))
158  g_value_set_boxed(value, &sx->last_date);
159  break;
160  case PROP_INSTANCE_COUNT:
161  g_value_set_int(value, sx->instance_num);
162  break;
163  case PROP_TEMPLATE_ACCOUNT:
164  g_value_take_object(value, sx->template_acct);
165  break;
166  default:
167  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
168  break;
169  }
170 }
171 
172 static void
173 gnc_schedxaction_set_property (GObject *object,
174  guint prop_id,
175  const GValue *value,
176  GParamSpec *pspec)
177 {
178  SchedXaction *sx;
179 
180  g_return_if_fail(GNC_IS_SCHEDXACTION(object));
181 
182  sx = GNC_SCHEDXACTION(object);
183  g_assert (qof_instance_get_editlevel(sx));
184 
185  switch (prop_id)
186  {
187  case PROP_NAME:
188  xaccSchedXactionSetName(sx, g_value_get_string(value));
189  break;
190  case PROP_ENABLED:
191  xaccSchedXactionSetEnabled(sx, g_value_get_boolean(value));
192  break;
193  case PROP_NUM_OCCURANCE:
194  xaccSchedXactionSetNumOccur(sx, g_value_get_int(value));
195  break;
196  case PROP_REM_OCCURANCE:
197  xaccSchedXactionSetRemOccur(sx, g_value_get_int(value));
198  break;
199  case PROP_AUTO_CREATE:
200  xaccSchedXactionSetAutoCreate(sx, g_value_get_boolean(value), sx->autoCreateNotify);
201  break;
202  case PROP_AUTO_CREATE_NOTIFY:
203  xaccSchedXactionSetAutoCreate(sx, sx->autoCreateOption, g_value_get_boolean(value));
204  break;
205  case PROP_ADVANCE_CREATION_DAYS:
206  xaccSchedXactionSetAdvanceCreation(sx, g_value_get_int(value));
207  break;
208  case PROP_ADVANCE_REMINDER_DAYS:
209  xaccSchedXactionSetAdvanceReminder(sx, g_value_get_int(value));
210  break;
211  case PROP_START_DATE:
212  /* Note: when passed through a boxed gvalue, the julian value of the date is copied.
213  The date may appear invalid until a function requiring for dmy calculation is
214  called. */
215  xaccSchedXactionSetStartDate(sx, static_cast<const GDate*>(g_value_get_boxed(value)));
216  break;
217  case PROP_END_DATE:
218  /* Note: when passed through a boxed gvalue, the julian value of the date is copied.
219  The date may appear invalid until a function requiring for dmy calculation is
220  called. */
221  xaccSchedXactionSetEndDate(sx, static_cast<const GDate*>(g_value_get_boxed(value)));
222  break;
223  case PROP_LAST_OCCURANCE_DATE:
224  /* Note: when passed through a boxed gvalue, the julian value of the date is copied.
225  The date may appear invalid until a function requiring for dmy calculation is
226  called. */
227  xaccSchedXactionSetLastOccurDate(sx, static_cast<const GDate*>(g_value_get_boxed(value)));
228  break;
229  case PROP_INSTANCE_COUNT:
230  gnc_sx_set_instance_count(sx, g_value_get_int(value));
231  break;
232  case PROP_TEMPLATE_ACCOUNT:
233  sx_set_template_account(sx, GNC_ACCOUNT(g_value_get_object(value)));
234  break;
235  default:
236  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
237  break;
238  }
239 }
240 
241 static void
242 gnc_schedxaction_class_init (SchedXactionClass *klass)
243 {
244  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
245 
246  gobject_class->dispose = gnc_schedxaction_dispose;
247  gobject_class->finalize = gnc_schedxaction_finalize;
248  gobject_class->set_property = gnc_schedxaction_set_property;
249  gobject_class->get_property = gnc_schedxaction_get_property;
250 
251  g_object_class_install_property
252  (gobject_class,
253  PROP_NAME,
254  g_param_spec_string ("name",
255  "Scheduled Transaction Name",
256  "The name is an arbitrary string "
257  "assigned by the user. It is intended to "
258  "a short, 5 to 30 character long string "
259  "that is displayed by the GUI.",
260  NULL,
261  G_PARAM_READWRITE));
262 
263  g_object_class_install_property
264  (gobject_class,
265  PROP_ENABLED,
266  g_param_spec_boolean ("enabled",
267  "Enabled",
268  "TRUE if the scheduled transaction is enabled.",
269  TRUE,
270  G_PARAM_READWRITE));
271 
272  g_object_class_install_property
273  (gobject_class,
274  PROP_NUM_OCCURANCE,
275  g_param_spec_int ("num-occurance",
276  "Number of occurrences",
277  "Total number of occurrences for this scheduled transaction.",
278  0,
279  G_MAXINT16,
280  1,
281  G_PARAM_READWRITE));
282 
283  g_object_class_install_property
284  (gobject_class,
285  PROP_REM_OCCURANCE,
286  g_param_spec_int ("rem-occurance",
287  "Number of occurrences remaining",
288  "Remaining number of occurrences for this scheduled transaction.",
289  0,
290  G_MAXINT16,
291  1,
292  G_PARAM_READWRITE));
293 
294  g_object_class_install_property
295  (gobject_class,
296  PROP_AUTO_CREATE,
297  g_param_spec_boolean ("auto-create",
298  "Auto-create",
299  "TRUE if the transaction will be automatically "
300  "created when its time comes.",
301  FALSE,
302  G_PARAM_READWRITE));
303 
304  g_object_class_install_property
305  (gobject_class,
306  PROP_AUTO_CREATE_NOTIFY,
307  g_param_spec_boolean ("auto-create-notify",
308  "Auto-create-notify",
309  "TRUE if the the user will be notified when the transaction "
310  "is automatically created.",
311  FALSE,
312  G_PARAM_READWRITE));
313 
314  g_object_class_install_property
315  (gobject_class,
316  PROP_ADVANCE_CREATION_DAYS,
317  g_param_spec_int ("advance-creation-days",
318  "Days in advance to create",
319  "Number of days in advance to create this scheduled transaction.",
320  0,
321  G_MAXINT16,
322  0,
323  G_PARAM_READWRITE));
324 
325  g_object_class_install_property
326  (gobject_class,
327  PROP_ADVANCE_REMINDER_DAYS,
328  g_param_spec_int ("advance-reminder-days",
329  "Days in advance to remind",
330  "Number of days in advance to remind about this scheduled transaction.",
331  0,
332  G_MAXINT16,
333  0,
334  G_PARAM_READWRITE));
335 
336  g_object_class_install_property
337  (gobject_class,
338  PROP_START_DATE,
339  g_param_spec_boxed("start-date",
340  "Start Date",
341  "Date for the first occurrence for the scheduled transaction.",
342  G_TYPE_DATE,
343  G_PARAM_READWRITE));
344 
345  g_object_class_install_property
346  (gobject_class,
347  PROP_END_DATE,
348  g_param_spec_boxed("end-date",
349  "End Date",
350  "Date for the scheduled transaction to end.",
351  G_TYPE_DATE,
352  G_PARAM_READWRITE));
353 
354  g_object_class_install_property
355  (gobject_class,
356  PROP_LAST_OCCURANCE_DATE,
357  g_param_spec_boxed("last-occurance-date",
358  "Last Occurrence Date",
359  "Date for the last occurrence of the scheduled transaction.",
360  G_TYPE_DATE,
361  G_PARAM_READWRITE));
362 
363  g_object_class_install_property
364  (gobject_class,
365  PROP_INSTANCE_COUNT,
366  g_param_spec_int ("instance-count",
367  "Instance count",
368  "Number of instances of this scheduled transaction.",
369  0,
370  G_MAXINT16,
371  0,
372  G_PARAM_READWRITE));
373 
374  g_object_class_install_property
375  (gobject_class,
376  PROP_TEMPLATE_ACCOUNT,
377  g_param_spec_object("template-account",
378  "Template account",
379  "Account which holds the template transactions.",
380  GNC_TYPE_ACCOUNT,
381  G_PARAM_READWRITE));
382 }
383 
384 static void
385 xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
386 {
387  Account *ra;
388  const GncGUID *guid;
389  gchar guidstr[GUID_ENCODING_LENGTH+1];
390 
391  qof_instance_init_data (&sx->inst, GNC_ID_SCHEDXACTION, book);
392 
393  /* create a new template account for our splits */
394  sx->template_acct = xaccMallocAccount(book);
395  guid = qof_instance_get_guid( sx );
396  xaccAccountBeginEdit( sx->template_acct );
397  guid_to_string_buff( guid, guidstr );
398  xaccAccountSetName( sx->template_acct, guidstr);
400  (sx->template_acct,
401  gnc_commodity_table_lookup( gnc_commodity_table_get_table(book),
402  GNC_COMMODITY_NS_TEMPLATE, "template") );
403  xaccAccountSetType( sx->template_acct, ACCT_TYPE_BANK );
404  xaccAccountCommitEdit( sx->template_acct );
405  ra = gnc_book_get_template_root( book );
406  gnc_account_append_child( ra, sx->template_acct );
407 }
408 
409 SchedXaction*
411 {
412  SchedXaction *sx;
413 
414  g_return_val_if_fail (book, NULL);
415 
416  sx = GNC_SX(g_object_new(GNC_TYPE_SCHEDXACTION, NULL));
417  xaccSchedXactionInit( sx, book );
418  qof_event_gen( &sx->inst, QOF_EVENT_CREATE , NULL);
419 
420  return sx;
421 }
422 
423 static void
424 delete_template_trans(SchedXaction *sx)
425 {
426  std::unordered_set<Transaction*> txns;
427  auto& splits{xaccAccountGetSplits (sx->template_acct)};
428  std::for_each (splits.begin(), splits.end(),
429  [&txns](auto s){ txns.insert (xaccSplitGetParent (s)); });
430  std::for_each (txns.begin(), txns.end(),
431  [](auto t)
432  {
433  xaccTransBeginEdit (t);
434  xaccTransDestroy (t);
436  });
437  return;
438 }
439 
440 void
441 sx_set_template_account (SchedXaction *sx, Account *account)
442 {
443  Account *old;
444 
445  old = sx->template_acct;
446  sx->template_acct = account;
447  if (old)
448  {
450  xaccAccountDestroy(old);
451  }
452 }
453 
454 void
455 xaccSchedXactionDestroy( SchedXaction *sx )
456 {
457  qof_instance_set_destroying( QOF_INSTANCE(sx), TRUE );
458  gnc_sx_commit_edit( sx );
459 }
460 
461 static void
462 xaccSchedXactionFree( SchedXaction *sx )
463 {
464  if ( sx == NULL ) return;
465 
466  qof_event_gen( &sx->inst, QOF_EVENT_DESTROY , NULL);
467 
468  if ( sx->name )
469  g_free( sx->name );
470 
471  /*
472  * we have to delete the transactions in the
473  * template account ourselves
474  */
475 
476  delete_template_trans( sx );
477 
478  xaccAccountBeginEdit( sx->template_acct );
479  xaccAccountDestroy( sx->template_acct );
480 
481  g_list_free_full (sx->deferredList, g_free);
482 
483  /* a GList of Recurrences */
484  g_list_free_full (sx->schedule, g_free);
485 
486  /* qof_instance_release (&sx->inst); */
487  g_object_unref( sx );
488 }
489 
490 /* ============================================================ */
491 
492 void
493 gnc_sx_begin_edit (SchedXaction *sx)
494 {
495  qof_begin_edit (&sx->inst);
496 }
497 
498 static void sx_free(QofInstance* inst )
499 {
500  xaccSchedXactionFree( GNC_SX(inst) );
501 }
502 
503 static void commit_err (QofInstance *inst, QofBackendError errcode)
504 {
505  g_critical("Failed to commit: %d", errcode);
506  gnc_engine_signal_commit_error( errcode );
507 }
508 
509 static void commit_done(QofInstance *inst)
510 {
511  qof_event_gen (inst, QOF_EVENT_MODIFY, NULL);
512 }
513 
514 void
515 gnc_sx_commit_edit (SchedXaction *sx)
516 {
517  if (!qof_commit_edit (QOF_INSTANCE(sx))) return;
518  qof_commit_edit_part2 (&sx->inst, commit_err, commit_done, sx_free);
519 }
520 
521 /* ============================================================ */
522 
523 GList*
524 gnc_sx_get_schedule(const SchedXaction *sx)
525 {
526  return sx->schedule;
527 }
528 
529 void
530 gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
531 {
532  g_return_if_fail(sx);
533  gnc_sx_begin_edit(sx);
534  sx->schedule = schedule;
535  qof_instance_set_dirty(&sx->inst);
536  gnc_sx_commit_edit(sx);
537 }
538 
539 gchar *
540 xaccSchedXactionGetName( const SchedXaction *sx )
541 {
542  return sx->name;
543 }
544 
545 void
546 xaccSchedXactionSetName( SchedXaction *sx, const gchar *newName )
547 {
548  g_return_if_fail( newName != NULL );
549  gnc_sx_begin_edit(sx);
550  if ( sx->name != NULL )
551  {
552  g_free( sx->name );
553  sx->name = NULL;
554  }
555  sx->name = g_strdup( newName );
556  qof_instance_set_dirty(&sx->inst);
557  gnc_sx_commit_edit(sx);
558 }
559 
560 const GDate*
561 xaccSchedXactionGetStartDate(const SchedXaction *sx )
562 {
563  g_assert (sx);
564  return &sx->start_date;
565 }
566 
567 time64
568 xaccSchedXactionGetStartDateTT(const SchedXaction *sx )
569 {
570  g_assert (sx);
571  return gdate_to_time64(sx->start_date);
572 }
573 
574 void
575 xaccSchedXactionSetStartDate( SchedXaction *sx, const GDate* newStart )
576 {
577  if ( newStart == NULL || !g_date_valid( newStart ))
578  {
579  /* XXX: I reject the bad data - is this the right
580  * thing to do <rgmerk>.
581  * This warning is only human readable - the caller
582  * doesn't know the call failed. This is bad
583  */
584  g_critical("Invalid Start Date");
585  return;
586  }
587  gnc_sx_begin_edit(sx);
588  sx->start_date = *newStart;
589  qof_instance_set_dirty(&sx->inst);
590  gnc_sx_commit_edit(sx);
591 }
592 
593 void
594 xaccSchedXactionSetStartDateTT( SchedXaction *sx, const time64 newStart )
595 {
596  if ( newStart == INT64_MAX )
597  {
598  /* XXX: I reject the bad data - is this the right
599  * thing to do <rgmerk>.
600  * This warning is only human readable - the caller
601  * doesn't know the call failed. This is bad
602  */
603  g_critical("Invalid Start Date");
604  return;
605  }
606  gnc_sx_begin_edit(sx);
607  gnc_gdate_set_time64(&sx->start_date, newStart);
608  qof_instance_set_dirty(&sx->inst);
609  gnc_sx_commit_edit(sx);
610 }
611 
612 gboolean
613 xaccSchedXactionHasEndDate( const SchedXaction *sx )
614 {
615  return sx != NULL && g_date_valid( &sx->end_date );
616 }
617 
618 const GDate*
619 xaccSchedXactionGetEndDate(const SchedXaction *sx )
620 {
621  g_assert (sx);
622  return &sx->end_date;
623 }
624 
625 void
626 xaccSchedXactionSetEndDate( SchedXaction *sx, const GDate *newEnd )
627 {
628 /* Note that an invalid GDate IS a permissible value: It means that
629  * the SX is to run "forever". See gnc_sxed_save_sx() and
630  * schedXact_editor_populate() in dialog-sx-editor.c.
631  */
632  if (newEnd == NULL ||
633  (g_date_valid(newEnd) && g_date_compare( newEnd, &sx->start_date ) < 0 ))
634  {
635  /* XXX: I reject the bad data - is this the right
636  * thing to do <rgmerk>.
637  * This warning is only human readable - the caller
638  * doesn't know the call failed. This is bad
639  */
640  g_critical("Bad End Date: Invalid or before Start Date");
641  return;
642  }
643 
644  gnc_sx_begin_edit(sx);
645  sx->end_date = *newEnd;
646  qof_instance_set_dirty(&sx->inst);
647  gnc_sx_commit_edit(sx);
648 }
649 
650 const GDate*
651 xaccSchedXactionGetLastOccurDate(const SchedXaction *sx )
652 {
653  return &sx->last_date;
654 }
655 
656 time64
657 xaccSchedXactionGetLastOccurDateTT(const SchedXaction *sx )
658 {
659  return gdate_to_time64(sx->last_date);
660 }
661 
662 void
663 xaccSchedXactionSetLastOccurDate(SchedXaction *sx, const GDate* new_last_occur)
664 {
665  g_return_if_fail (new_last_occur != NULL);
666  if (g_date_valid(&sx->last_date)
667  && g_date_compare(&sx->last_date, new_last_occur) == 0)
668  return;
669  gnc_sx_begin_edit(sx);
670  sx->last_date = *new_last_occur;
671  qof_instance_set_dirty(&sx->inst);
672  gnc_sx_commit_edit(sx);
673 }
674 
675 void
676 xaccSchedXactionSetLastOccurDateTT(SchedXaction *sx, time64 new_last_occur)
677 {
678  GDate last_occur;
679  g_return_if_fail (new_last_occur != INT64_MAX);
680  gnc_gdate_set_time64(&last_occur, new_last_occur);
681  if (g_date_valid(&sx->last_date)
682  && g_date_compare(&sx->last_date, &last_occur) == 0)
683  return;
684  gnc_sx_begin_edit(sx);
685  sx->last_date = last_occur;
686  qof_instance_set_dirty(&sx->inst);
687  gnc_sx_commit_edit(sx);
688 }
689 
690 gboolean
691 xaccSchedXactionHasOccurDef( const SchedXaction *sx )
692 {
693  return ( xaccSchedXactionGetNumOccur( sx ) != 0 );
694 }
695 
696 gint
697 xaccSchedXactionGetNumOccur( const SchedXaction *sx )
698 {
699  return sx->num_occurances_total;
700 }
701 
702 void
703 xaccSchedXactionSetNumOccur(SchedXaction *sx, gint new_num)
704 {
705  if (sx->num_occurances_total == new_num)
706  return;
707  gnc_sx_begin_edit(sx);
708  sx->num_occurances_remain = sx->num_occurances_total = new_num;
709  qof_instance_set_dirty(&sx->inst);
710  gnc_sx_commit_edit(sx);
711 }
712 
713 gint
714 xaccSchedXactionGetRemOccur( const SchedXaction *sx )
715 {
716  return sx->num_occurances_remain;
717 }
718 
719 void
720 xaccSchedXactionSetRemOccur(SchedXaction *sx, gint num_remain)
721 {
722  /* FIXME This condition can be tightened up */
723  if (num_remain > sx->num_occurances_total)
724  {
725  g_warning("number remaining [%d] > total occurrences [%d]",
726  num_remain, sx->num_occurances_total);
727  }
728  else
729  {
730  if (num_remain == sx->num_occurances_remain)
731  return;
732  gnc_sx_begin_edit(sx);
733  sx->num_occurances_remain = num_remain;
734  qof_instance_set_dirty(&sx->inst);
735  gnc_sx_commit_edit(sx);
736  }
737 }
738 
739 gint gnc_sx_get_num_occur_daterange(const SchedXaction *sx, const GDate* start_date, const GDate* end_date)
740 {
741  gint result = 0;
742  SXTmpStateData *tmpState;
743  gboolean countFirstDate;
744 
745  /* SX still active? If not, return now. */
747  && xaccSchedXactionGetRemOccur(sx) <= 0)
748  || (xaccSchedXactionHasEndDate(sx)
749  && g_date_compare(xaccSchedXactionGetEndDate(sx), start_date) < 0))
750  {
751  return result;
752  }
753 
754  tmpState = gnc_sx_create_temporal_state (sx);
755 
756  /* Should we count the first valid date we encounter? Only if the
757  * SX has not yet occurred so far, or if its last valid date was
758  * before the start date. */
759  countFirstDate = !g_date_valid(&tmpState->last_date)
760  || (g_date_compare(&tmpState->last_date, start_date) < 0);
761 
762  /* No valid date? SX has never occurred so far. */
763  if (!g_date_valid(&tmpState->last_date))
764  {
765  /* SX has never occurred so far */
766  gnc_sx_incr_temporal_state (sx, tmpState);
767  if (xaccSchedXactionHasOccurDef(sx) && tmpState->num_occur_rem < 0)
768  {
769  g_free (tmpState);
770  return result;
771  }
772  }
773 
774  /* Increase the tmpState until we are in our interval of
775  * interest. Only calculate anything if the sx hasn't already
776  * ended. */
777  while (g_date_compare(&tmpState->last_date, start_date) < 0)
778  {
779  gnc_sx_incr_temporal_state (sx, tmpState);
780  if (xaccSchedXactionHasOccurDef(sx) && tmpState->num_occur_rem < 0)
781  {
782  g_free (tmpState);
783  return result;
784  }
785  }
786 
787  /* Now we are in our interval of interest. Increment the
788  * occurrence date until we are beyond the end of our
789  * interval. Make sure to check for invalid dates here: It means
790  * the SX has ended. */
791  while (g_date_valid(&tmpState->last_date)
792  && (g_date_compare(&tmpState->last_date, end_date) <= 0)
793  && (!xaccSchedXactionHasEndDate(sx)
794  || g_date_compare(&tmpState->last_date, xaccSchedXactionGetEndDate(sx)) <= 0)
796  /* The >=0 (i.e. the ==) is important here, otherwise
797  * we miss the last valid occurrence of a SX which is
798  * limited by num_occur */
799  || tmpState->num_occur_rem >= 0))
800  {
801  ++result;
802  gnc_sx_incr_temporal_state (sx, tmpState);
803  }
804 
805  /* If the first valid date shouldn't be counted, decrease the
806  * result number by one. */
807  if (!countFirstDate && result > 0)
808  --result;
809 
810  g_free (tmpState);
811  return result;
812 }
813 
814 gboolean
815 xaccSchedXactionGetEnabled( const SchedXaction *sx )
816 {
817  return sx->enabled;
818 }
819 
820 void
821 xaccSchedXactionSetEnabled( SchedXaction *sx, gboolean newEnabled)
822 {
823  gnc_sx_begin_edit(sx);
824  sx->enabled = newEnabled;
825  qof_instance_set_dirty(&sx->inst);
826  gnc_sx_commit_edit(sx);
827 }
828 
829 void
830 xaccSchedXactionGetAutoCreate( const SchedXaction *sx,
831  gboolean *outAutoCreate,
832  gboolean *outNotify )
833 {
834  if (outAutoCreate != NULL)
835  *outAutoCreate = sx->autoCreateOption;
836  if (outNotify != NULL)
837  *outNotify = sx->autoCreateNotify;
838  return;
839 }
840 
841 void
842 xaccSchedXactionSetAutoCreate( SchedXaction *sx,
843  gboolean newAutoCreate,
844  gboolean newNotify )
845 {
846 
847  gnc_sx_begin_edit(sx);
848  sx->autoCreateOption = newAutoCreate;
849  sx->autoCreateNotify = newNotify;
850  qof_instance_set_dirty(&sx->inst);
851  gnc_sx_commit_edit(sx);
852  return;
853 }
854 
855 gint
856 xaccSchedXactionGetAdvanceCreation( const SchedXaction *sx )
857 {
858  return sx->advanceCreateDays;
859 }
860 
861 void
862 xaccSchedXactionSetAdvanceCreation( SchedXaction *sx, gint createDays )
863 {
864  gnc_sx_begin_edit(sx);
865  sx->advanceCreateDays = createDays;
866  qof_instance_set_dirty(&sx->inst);
867  gnc_sx_commit_edit(sx);
868 }
869 
870 gint
871 xaccSchedXactionGetAdvanceReminder( const SchedXaction *sx )
872 {
873  return sx->advanceRemindDays;
874 }
875 
876 void
877 xaccSchedXactionSetAdvanceReminder( SchedXaction *sx, gint reminderDays )
878 {
879  gnc_sx_begin_edit(sx);
880  sx->advanceRemindDays = reminderDays;
881  qof_instance_set_dirty(&sx->inst);
882  gnc_sx_commit_edit(sx);
883 }
884 
885 GDate
886 xaccSchedXactionGetNextInstance (const SchedXaction *sx, SXTmpStateData *tsd)
887 {
888  GDate prev_occur, next_occur;
889 
890  g_date_clear( &prev_occur, 1 );
891  if ( tsd != NULL )
892  prev_occur = tsd->last_date;
893 
894  /* If prev_occur is in the "cleared" state and sx->start_date isn't, then
895  * we're at the beginning. We want to pretend prev_occur is the day before
896  * the start_date in case the start_date is today so that the SX will fire
897  * today. If start_date isn't valid either then the SX will fire anyway, no
898  * harm done. prev_occur cannot be before start_date either.
899  */
900  if (g_date_valid (&sx->start_date) && (!g_date_valid ( &prev_occur ) || g_date_compare (&prev_occur, &sx->start_date)<0))
901  {
902  /* We must be at the beginning. */
903  prev_occur = sx->start_date;
904  g_date_subtract_days (&prev_occur, 1 );
905  }
906 
907  recurrenceListNextInstance(sx->schedule, &prev_occur, &next_occur);
908 
909  if ( xaccSchedXactionHasEndDate( sx ) )
910  {
911  const GDate *end_date = xaccSchedXactionGetEndDate( sx );
912  if ( g_date_compare( &next_occur, end_date ) > 0 )
913  {
914  g_date_clear( &next_occur, 1 );
915  }
916  }
917  else if ( xaccSchedXactionHasOccurDef( sx ) )
918  {
919  if ((tsd && tsd->num_occur_rem == 0) ||
920  (!tsd && sx->num_occurances_remain == 0 ))
921  {
922  g_date_clear( &next_occur, 1 );
923  }
924  }
925  return next_occur;
926 }
927 
928 gint
929 gnc_sx_get_instance_count( const SchedXaction *sx, SXTmpStateData *stateData )
930 {
931  gint toRet = -1;
932  SXTmpStateData *tsd;
933 
934  if ( stateData )
935  {
936  tsd = (SXTmpStateData*)stateData;
937  toRet = tsd->num_inst;
938  }
939  else
940  {
941  toRet = sx->instance_num;
942  }
943 
944  return toRet;
945 }
946 
947 void
948 gnc_sx_set_instance_count(SchedXaction *sx, gint instance_num)
949 {
950  g_return_if_fail(sx);
951  if (sx->instance_num == instance_num)
952  return;
953  gnc_sx_begin_edit(sx);
954  sx->instance_num = instance_num;
955  qof_instance_set_dirty(&sx->inst);
956  gnc_sx_commit_edit(sx);
957 }
958 
959 GList *
960 xaccSchedXactionGetSplits( const SchedXaction *sx )
961 {
962  g_return_val_if_fail( sx, NULL );
963  return xaccAccountGetSplitList(sx->template_acct);
964 }
965 
966 static Split *
967 pack_split_info (TTSplitInfoPtr s_info, Account *parent_acct,
968  Transaction *parent_trans, QofBook *book)
969 {
970  Split *split;
971  const gchar *credit_formula;
972  const gchar *debit_formula;
973  const GncGUID *acc_guid;
974 
975  split = xaccMallocSplit(book);
976 
977  xaccSplitSetMemo(split, s_info->get_memo());
978 
979  /* Set split-action with gnc_set_num_action which is the same as
980  * xaccSplitSetAction with these arguments */
981  gnc_set_num_action(NULL, split, NULL, s_info->get_action());
982 
983  xaccAccountInsertSplit(parent_acct,
984  split);
985 
986  credit_formula = s_info->get_credit_formula ();
987  debit_formula = s_info->get_debit_formula ();
988  acc_guid = qof_entity_get_guid(QOF_INSTANCE(s_info->get_account ()));
989  qof_instance_set (QOF_INSTANCE (split),
990  "sx-credit-formula", credit_formula,
991  "sx-debit-formula", debit_formula,
992  "sx-account", acc_guid,
993  NULL);
994 
995  return split;
996 }
997 
998 
999 void
1000 xaccSchedXactionSetTemplateTrans (SchedXaction *sx, const TTInfoVec& tt_vec, QofBook *book)
1001 {
1002  Transaction *new_trans;
1003 
1004  g_return_if_fail (book);
1005 
1006  /* delete any old transactions, if there are any */
1007  delete_template_trans( sx );
1008 
1009  for (auto tti : tt_vec)
1010  {
1011  new_trans = xaccMallocTransaction(book);
1012 
1013  xaccTransBeginEdit(new_trans);
1014  xaccTransSetDescription(new_trans, tti->get_description());
1016  /* Set tran-num with gnc_set_num_action which is the same as
1017  * xaccTransSetNum with these arguments */
1018  gnc_set_num_action (new_trans, NULL, tti->get_num(), NULL);
1019  xaccTransSetNotes (new_trans, tti->get_notes ());
1020  xaccTransSetCurrency (new_trans, tti->get_currency ());
1021 
1022  for (auto s_info : tti->get_template_splits())
1023  {
1024  auto new_split = pack_split_info(s_info, sx->template_acct, new_trans, book);
1025  xaccTransAppendSplit(new_trans, new_split);
1026  }
1027  xaccTransCommitEdit(new_trans);
1028  }
1029 }
1030 
1032 gnc_sx_create_temporal_state(const SchedXaction *sx )
1033 {
1034  auto toRet = g_new0 (SXTmpStateData, 1);
1035  if (g_date_valid (&(sx->last_date)))
1036  toRet->last_date = sx->last_date;
1037  else
1038  g_date_set_dmy (&toRet->last_date, 1, static_cast<GDateMonth>(1), 1970);
1039  toRet->num_occur_rem = sx->num_occurances_remain;
1040  toRet->num_inst = sx->instance_num;
1041  return toRet;
1042 }
1043 
1044 void
1045 gnc_sx_incr_temporal_state(const SchedXaction *sx, SXTmpStateData *tsd )
1046 {
1047  g_return_if_fail(tsd != NULL);
1048  tsd->last_date = xaccSchedXactionGetNextInstance (sx, tsd);
1049  if (xaccSchedXactionHasOccurDef (sx))
1050  {
1051  --tsd->num_occur_rem;
1052  }
1053  ++tsd->num_inst;
1054 }
1055 
1056 void
1058 {
1059  g_free(tsd);
1060 }
1061 
1064 {
1065  SXTmpStateData *toRet = NULL;
1066 
1067  if(tsd)
1068  {
1069  toRet = g_new(SXTmpStateData, 1);
1070  *toRet = *tsd;
1071  }
1072 
1073  return toRet;
1074 }
1075 
1076 static gint
1077 _temporal_state_data_cmp( gconstpointer a, gconstpointer b )
1078 {
1079  const SXTmpStateData *tsd_a = (SXTmpStateData*)a;
1080  const SXTmpStateData *tsd_b = (SXTmpStateData*)b;
1081 
1082  if ( !tsd_a && !tsd_b )
1083  return 0;
1084  if (tsd_a == tsd_b)
1085  return 0;
1086  if ( !tsd_a )
1087  return 1;
1088  if ( !tsd_b )
1089  return -1;
1090  return g_date_compare( &tsd_a->last_date,
1091  &tsd_b->last_date );
1092 }
1093 
1098 void
1099 gnc_sx_add_defer_instance( SchedXaction *sx, void *deferStateData )
1100 {
1101  sx->deferredList = g_list_insert_sorted( sx->deferredList,
1102  deferStateData,
1103  _temporal_state_data_cmp );
1104 }
1105 
1110 void
1111 gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData )
1112 {
1113  GList *found_by_value;
1114 
1115  found_by_value = g_list_find_custom(
1116  sx->deferredList, deferStateData, _temporal_state_data_cmp);
1117  if (found_by_value == NULL)
1118  {
1119  g_warning("unable to find deferred instance");
1120  return;
1121  }
1122 
1123  g_free (found_by_value->data);
1124  sx->deferredList = g_list_delete_link(sx->deferredList, found_by_value);
1125 }
1126 
1136 GList*
1137 gnc_sx_get_defer_instances( SchedXaction *sx )
1138 {
1139  return sx->deferredList;
1140 }
1141 
1142 static void
1143 destroy_sx_on_book_close(QofInstance *ent, gpointer data)
1144 {
1145  SchedXaction* sx = GNC_SCHEDXACTION(ent);
1146 
1147  gnc_sx_begin_edit(sx);
1149 }
1150 
1156 static void
1157 gnc_sx_book_end(QofBook* book)
1158 {
1159  QofCollection *col;
1160 
1161  col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
1162  qof_collection_foreach(col, destroy_sx_on_book_close, NULL);
1163 
1164  // Now destroy the template root account
1165  gnc_book_set_template_root (book, NULL);
1166 }
1167 
1168 #ifdef _MSC_VER
1169 /* MSVC compiler doesn't have C99 "designated initializers"
1170  * so we wrap them in a macro that is empty on MSVC. */
1171 # define DI(x) /* */
1172 #else
1173 # define DI(x) x
1174 #endif
1175 static QofObject SXDesc =
1176 {
1177  DI(.interface_version = ) QOF_OBJECT_VERSION,
1178  DI(.e_type = ) GNC_SX_ID,
1179  DI(.type_label = ) "Scheduled Transaction",
1180  DI(.create = ) (void* (*)(QofBook*))xaccSchedXactionMalloc,
1181  DI(.book_begin = ) NULL,
1182  DI(.book_end = ) gnc_sx_book_end,
1183  DI(.is_dirty = ) qof_collection_is_dirty,
1184  DI(.mark_clean = ) qof_collection_mark_clean,
1185  DI(.foreach = ) qof_collection_foreach,
1186  DI(.printable = ) NULL,
1187  DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
1188 };
1189 
1190 gboolean
1192 {
1193  static QofParam params[] =
1194  {
1195  {
1196  GNC_SX_NAME, QOF_TYPE_STRING, (QofAccessFunc)xaccSchedXactionGetName,
1198  },
1199  {
1200  GNC_SX_START_DATE, QOF_TYPE_DATE, (QofAccessFunc)xaccSchedXactionGetStartDateTT,
1201  (QofSetterFunc)xaccSchedXactionSetStartDateTT
1202  },
1203  {
1204  GNC_SX_LAST_DATE, QOF_TYPE_DATE, (QofAccessFunc)xaccSchedXactionGetLastOccurDateTT,
1205  (QofSetterFunc)xaccSchedXactionSetLastOccurDateTT
1206  },
1207  {
1208  GNC_SX_NUM_OCCUR, QOF_TYPE_INT64, (QofAccessFunc)xaccSchedXactionGetNumOccur,
1210  },
1211  {
1212  GNC_SX_REM_OCCUR, QOF_TYPE_INT64, (QofAccessFunc)xaccSchedXactionGetRemOccur,
1213  (QofSetterFunc)xaccSchedXactionSetRemOccur
1214  },
1215  { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
1216  { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
1217  { NULL },
1218  };
1219  qof_class_register(GNC_SX_ID, NULL, params);
1220  return qof_object_register(&SXDesc);
1221 }
const GDate * xaccSchedXactionGetEndDate(const SchedXaction *sx)
Returns invalid date when there is no end-date specified.
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Set the account&#39;s type.
Definition: Account.cpp:2418
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Definition: Transaction.h:381
void gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
void gnc_sx_set_instance_count(SchedXaction *sx, gint instance_num)
Sets the instance count to something other than the default.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
GList * gnc_sx_get_schedule(const SchedXaction *sx)
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship, and will then add the account as a child of the new parent.
Definition: Account.cpp:2776
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
SplitList * xaccAccountGetSplitList(const Account *acc)
The xaccAccountGetSplitList() routine returns a pointer to a GList of the splits in the account...
Definition: Account.cpp:3965
void gnc_sx_destroy_temporal_state(SXTmpStateData *tsd)
Frees the given stateDate object.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of &#39;dirty&#39; flag on collection.
Definition: qofid.cpp:255
void xaccSchedXactionSetNumOccur(SchedXaction *sx, gint new_num)
Set to &#39;0&#39; to turn off number-of-occurrences definition.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:57
void xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
STRUCTS.
SXTmpStateData * gnc_sx_create_temporal_state(const SchedXaction *sx)
Allocates a new SXTmpStateData object and fills it with the current state of the given sx...
void qof_instance_set(QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_set Group setting multiple parameters in a single begin/commit/rollback.
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
This function registers a new object class with the Qof subsystem.
Definition: qofclass.cpp:86
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
Account * gnc_book_get_template_root(const QofBook *book)
Returns the template group from the book.
Definition: SX-book.cpp:65
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
Definition: guid.cpp:173
Just the variable temporal bits from the SX structure.
Definition: SchedXaction.h:131
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
Definition: qofobject.h:63
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
Definition: qofquery.h:108
GDate xaccSchedXactionGetNextInstance(const SchedXaction *sx, SXTmpStateData *tsd)
Returns the next occurrence of a scheduled transaction.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
Definition: qofclass.h:185
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
gboolean SXRegister(void)
QOF registration.
void xaccAccountDestroy(Account *acc)
The xaccAccountDestroy() routine can be used to get rid of an account.
Definition: Account.cpp:1593
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
void gnc_sx_incr_temporal_state(const SchedXaction *sx, SXTmpStateData *tsd)
Calculates the next occurrence of the given SX and stores that occurrence in the remporalStateDate.
Account handling public routines.
Account public routines (C++ api)
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
Definition: guid.h:84
void gnc_sx_add_defer_instance(SchedXaction *sx, void *deferStateData)
Adds an instance to the deferred list of the SX.
Anchor Scheduled Transaction info in a book.
The bank account type denotes a savings or checking account held at a bank.
Definition: Account.h:107
gint gnc_sx_get_num_occur_daterange(const SchedXaction *sx, const GDate *start_date, const GDate *end_date)
Calculates and returns the number of occurrences of the given SX in the given date range (inclusive)...
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
Definition: gnc-date.cpp:1252
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
part2 – deal with the backend
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Definition: qofclass.h:178
SXTmpStateData * gnc_sx_clone_temporal_state(SXTmpStateData *tsd)
Allocates and returns a one-by-one copy of the given temporal state.
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
Definition: qofid.cpp:261
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
All type declarations for the whole Gnucash engine.
const GncGUID * qof_entity_get_guid(gconstpointer ent)
Split * xaccMallocSplit(QofBook *book)
Constructor.
Definition: gmock-Split.cpp:37
void xaccSchedXactionSetName(SchedXaction *sx, const gchar *newName)
A copy of the name is made.
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
Definition: gnc-date.cpp:1243
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition: Account.cpp:1479
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
Definition: Account.h:1048
void gnc_sx_remove_defer_instance(SchedXaction *sx, void *deferStateData)
Removes an instance from the deferred list.
Account * xaccMallocAccount(QofBook *book)
Constructor.
Definition: Account.cpp:1275
time64 gnc_time(time64 *tbuf)
get the current time
Definition: gnc-date.cpp:261
SchedXaction * xaccSchedXactionMalloc(QofBook *book)
Creates and initializes a scheduled transaction.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
Definition: qofbook.cpp:521
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition: gnc-date.h:87
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
Definition: qofobject.cpp:299
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
gboolean xaccSchedXactionHasOccurDef(const SchedXaction *sx)
Returns true if the scheduled transaction has a defined number of occurrences, false if not...
Scheduled Transactions public handling routines.
void xaccSchedXactionSetEndDate(SchedXaction *sx, const GDate *newEnd)
Set to an invalid GDate to turn off &#39;end-date&#39; definition.
API for Transactions and Splits (journal entries)
The type used to store guids in C.
Definition: guid.h:75
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1520
void xaccAccountSetName(Account *acc, const char *str)
Set the account&#39;s name.
Definition: Account.cpp:2439
void xaccSchedXactionDestroy(SchedXaction *sx)
Cleans up and frees a SchedXaction and its associated data.
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Set the account&#39;s commodity.
Definition: Account.cpp:2618
GList * gnc_sx_get_defer_instances(SchedXaction *sx)
Returns the defer list from the SX; this is a (date-)sorted temporal-state-data instance list...
gint gnc_sx_get_instance_count(const SchedXaction *sx, SXTmpStateData *stateData)
Get the instance count.