GnuCash  5.6-150-g038405b370+
Query.cpp
1 /********************************************************************\
2  * Query.c : api for finding transactions *
3  * Copyright (C) 2000 Bill Gribble <grib@billgribble.com> *
4  * Copyright (C) 2002 Linas Vepstas <linas@linas.org> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA gnu@gnu.org *
22 \********************************************************************/
23 
24 #include <config.h>
25 
26 #include <platform.h>
27 #if PLATFORM(WINDOWS)
28 #include <windows.h>
29 #endif
30 
31 #include <ctype.h>
32 #include <glib.h>
33 #include <math.h>
34 #include <string.h>
35 #include <sys/types.h>
36 
37 #include <regex.h>
38 #ifdef HAVE_UNISTD_H
39 # include <unistd.h>
40 #endif
41 
42 #include "gnc-lot.h"
43 #include "Account.h"
44 #include "Query.h"
45 #include "Transaction.h"
46 #include "TransactionP.hpp"
47 
48 static QofLogModule log_module = GNC_MOD_QUERY;
49 
50 static GSList *
51 build_param_list_internal (const char *first, va_list rest)
52 {
53  GSList *list = nullptr;
54  char const *param;
55 
56  for (param = first; param; param = va_arg (rest, const char *))
57  list = g_slist_prepend (list, (gpointer)param);
58 
59  return (g_slist_reverse (list));
60 }
61 
62 /********************************************************************
63  * xaccQueryGetSplitsUniqueTrans
64  * Get splits but no more than one from a given transaction.
65  ********************************************************************/
66 
67 SplitList *
68 xaccQueryGetSplitsUniqueTrans(QofQuery *q)
69 {
70  GList * splits = qof_query_run(q);
71  GList * current;
72  GList * result = nullptr;
73  GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
74 
75  for (current = splits; current; current = current->next)
76  {
77  Split *split = GNC_SPLIT (current->data);
78  Transaction *trans = xaccSplitGetParent (split);
79 
80  if (!g_hash_table_lookup (trans_hash, trans))
81  {
82  g_hash_table_insert (trans_hash, trans, trans);
83  result = g_list_prepend (result, split);
84  }
85  }
86 
87  g_hash_table_destroy (trans_hash);
88 
89  return g_list_reverse (result);
90 }
91 
92 /********************************************************************
93  * xaccQueryGetTransactions
94  * Get transactions matching the query terms, specifying whether
95  * we require some or all splits to match
96  ********************************************************************/
97 
98 static void
99 query_match_all_filter_func(gpointer key, gpointer value, gpointer user_data)
100 {
101  Transaction * t = GNC_TRANSACTION(key);
102  int num_matches = GPOINTER_TO_INT(value);
103  auto matches = static_cast<GList**>(user_data);
104 
105  if (num_matches == xaccTransCountSplits(t))
106  {
107  *matches = g_list_prepend(*matches, t);
108  }
109 }
110 
111 static void
112 query_match_any_filter_func(gpointer key, gpointer value, gpointer user_data)
113 {
114  Transaction * t = GNC_TRANSACTION(key);
115  auto matches = static_cast<GList**>(user_data);
116  *matches = g_list_prepend(*matches, t);
117 }
118 
119 TransList *
120 xaccQueryGetTransactions (QofQuery * q, query_txn_match_t runtype)
121 {
122  GList * splits = qof_query_run(q);
123  GList * current = nullptr;
124  GList * retval = nullptr;
125  GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
126  Transaction * trans = nullptr;
127  gpointer val = nullptr;
128  int count = 0;
129 
130  /* iterate over matching splits, incrementing a match-count in
131  * the hash table */
132  for (current = splits; current; current = current->next)
133  {
134  trans = xaccSplitGetParent(GNC_SPLIT(current->data));
135 
136  /* don't waste time looking up unless we need the count
137  * information */
138  if (runtype == QUERY_TXN_MATCH_ALL)
139  {
140  val = g_hash_table_lookup(trans_hash, trans);
141  count = GPOINTER_TO_INT(val);
142  }
143  g_hash_table_insert(trans_hash, trans, GINT_TO_POINTER(count + 1));
144  }
145 
146  /* now pick out the transactions that match */
147  if (runtype == QUERY_TXN_MATCH_ALL)
148  {
149  g_hash_table_foreach(trans_hash, query_match_all_filter_func,
150  &retval);
151  }
152  else
153  {
154  g_hash_table_foreach(trans_hash, query_match_any_filter_func,
155  &retval);
156  }
157 
158  g_hash_table_destroy(trans_hash);
159 
160  return retval;
161 }
162 
163 /********************************************************************
164  * xaccQueryGetLots
165  * Get lots matching the query terms, specifying whether
166  * we require some or all splits to match
167  ********************************************************************/
168 
169 static void
170 query_match_all_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
171 {
172  GNCLot * l = GNC_LOT(key);
173  int num_matches = GPOINTER_TO_INT(value);
174  auto matches = static_cast<GList**>(user_data);
175 
176  if (num_matches == gnc_lot_count_splits(l))
177  {
178  *matches = g_list_prepend(*matches, l);
179  }
180 }
181 
182 static void
183 query_match_any_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
184 {
185  GNCLot * t = GNC_LOT(key);
186  auto matches = static_cast<GList**>(user_data);
187  *matches = g_list_prepend(*matches, t);
188 }
189 
190 LotList *
191 xaccQueryGetLots (QofQuery * q, query_txn_match_t runtype)
192 {
193  GList * splits = qof_query_run(q);
194  GList * current = nullptr;
195  GList * retval = nullptr;
196  GHashTable * lot_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
197  GNCLot * lot = nullptr;
198  gpointer val = nullptr;
199  int count = 0;
200 
201  /* iterate over matching splits, incrementing a match-count in
202  * the hash table */
203  for (current = splits; current; current = current->next)
204  {
205  lot = xaccSplitGetLot((GNC_SPLIT (current->data)));
206 
207  /* don't waste time looking up unless we need the count
208  * information */
209  if (runtype == QUERY_TXN_MATCH_ALL)
210  {
211  val = g_hash_table_lookup(lot_hash, lot);
212  count = GPOINTER_TO_INT(val);
213  }
214  g_hash_table_insert(lot_hash, lot, GINT_TO_POINTER(count + 1));
215  }
216 
217  /* now pick out the transactions that match */
218  if (runtype == QUERY_TXN_MATCH_ALL)
219  {
220  g_hash_table_foreach(lot_hash, query_match_all_lot_filter_func,
221  &retval);
222  }
223  else
224  {
225  g_hash_table_foreach(lot_hash, query_match_any_lot_filter_func,
226  &retval);
227  }
228 
229  g_hash_table_destroy(lot_hash);
230 
231  return retval;
232 }
233 
234 /*******************************************************************
235  * match-adding API
236  *******************************************************************/
237 
238 void
239 xaccQueryAddAccountMatch(QofQuery *q, AccountList *acct_list,
240  QofGuidMatch how, QofQueryOp op)
241 {
242  GList *list = nullptr;
243 
244  if (!q) return;
245  for (; acct_list; acct_list = acct_list->next)
246  {
247  Account *acc = GNC_ACCOUNT (acct_list->data);
248  const GncGUID *guid;
249 
250  if (!acc)
251  {
252  PWARN ("acct_list has nullptr account");
253  continue;
254  }
255 
256  guid = qof_entity_get_guid (QOF_INSTANCE(acc));
257  if (!guid)
258  {
259  PWARN ("acct returns nullptr GncGUID");
260  continue;
261  }
262 
263  list = g_list_prepend (list, (gpointer)guid);
264  }
265  xaccQueryAddAccountGUIDMatch (q, list, how, op);
266  g_list_free (list);
267 }
268 
269 void
270 xaccQueryAddAccountGUIDMatch(QofQuery *q, AccountGUIDList *guid_list,
271  QofGuidMatch how, QofQueryOp op)
272 {
273  QofQueryPredData *pred_data;
274  GSList *param_list = nullptr;
275 
276  if (!q) return;
277 
278  if (!guid_list && how != QOF_GUID_MATCH_NULL)
279  {
280  g_warning("Got a nullptr guid_list but the QofGuidMatch is not MATCH_nullptr (but instead %d). In other words, the list of GUID matches is empty but it must contain something non-empty.", how);
281  /* qof_query_guid_predicate() would trigger a g_warning as well */
282  return;
283  }
284  pred_data = qof_query_guid_predicate (how, guid_list);
285  if (!pred_data)
286  return;
287 
288  switch (how)
289  {
290  case QOF_GUID_MATCH_ANY:
291  case QOF_GUID_MATCH_NONE:
292  param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID, nullptr);
293  break;
294  case QOF_GUID_MATCH_ALL:
295  param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_SPLITLIST,
296  SPLIT_ACCOUNT_GUID, nullptr);
297  break;
298  default:
299  PERR ("Invalid match type: %d", how);
300  break;
301  }
302 
303  qof_query_add_term (q, param_list, pred_data, op);
304 }
305 
306 void
307 xaccQueryAddSingleAccountMatch(QofQuery *q, Account *acc, QofQueryOp op)
308 {
309  GList *list;
310  const GncGUID *guid;
311 
312  if (!q || !acc)
313  return;
314 
315  guid = qof_entity_get_guid (QOF_INSTANCE(acc));
316  g_return_if_fail (guid);
317 
318  list = g_list_prepend (nullptr, (gpointer)guid);
319  xaccQueryAddAccountGUIDMatch (q, list, QOF_GUID_MATCH_ANY, op);
320  g_list_free (list);
321 }
322 
323 void
324 xaccQueryAddStringMatch (QofQuery* q, const char *matchstring,
325  gboolean case_sens, gboolean use_regexp,
326  QofQueryCompare how, QofQueryOp op,
327  const char * path, ...)
328 {
329  QofQueryPredData *pred_data;
330  GSList *param_list;
331  va_list ap;
332 
333  if (!path || !q)
334  return;
335 
336  pred_data = qof_query_string_predicate (how, (char *)matchstring,
337  (case_sens ? QOF_STRING_MATCH_NORMAL :
338  QOF_STRING_MATCH_CASEINSENSITIVE),
339  use_regexp);
340  if (!pred_data)
341  return;
342 
343  va_start (ap, path);
344  param_list = build_param_list_internal (path, ap);
345  va_end (ap);
346 
347  qof_query_add_term (q, param_list, pred_data, op);
348 }
349 
350 void
351 xaccQueryAddNumericMatch (QofQuery *q, gnc_numeric amount, QofNumericMatch sign,
352  QofQueryCompare how, QofQueryOp op,
353  const char * path, ...)
354 {
355  QofQueryPredData *pred_data;
356  GSList *param_list;
357  va_list ap;
358 
359  if (!q || !path)
360  return;
361 
362  pred_data = qof_query_numeric_predicate (how, sign, amount);
363  if (!pred_data)
364  return;
365 
366  va_start (ap, path);
367  param_list = build_param_list_internal (path, ap);
368  va_end (ap);
369 
370  qof_query_add_term (q, param_list, pred_data, op);
371 }
372 
373 /* The DateMatch queries match transactions whose posted date
374  * is in a date range. If use_start is TRUE, then a matching
375  * posted date will be greater than the start date. If
376  * use_end is TRUE, then a match occurs for posted dates earlier
377  * than the end date. If both flags are set, then *both*
378  * conditions must hold ('and'). If neither flag is set, then
379  * all transactions are matched.
380  */
381 
382 void
383 xaccQueryAddDateMatchTT (QofQuery * q,
384  gboolean use_start, time64 stt,
385  gboolean use_end, time64 ett,
386  QofQueryOp op)
387 {
388  QofQuery *tmp_q = nullptr;
389  QofQueryPredData *pred_data;
390  GSList *param_list;
391 
392  if (!q || (!use_start && !use_end))
393  return;
394 
395  tmp_q = qof_query_create ();
396 
397  if (use_start)
398  {
399  pred_data = qof_query_date_predicate (QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, stt);
400  if (!pred_data)
401  {
402  qof_query_destroy (tmp_q);
403  return;
404  }
405 
406  param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
407  qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
408  }
409 
410  if (use_end)
411  {
412  pred_data = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, ett);
413  if (!pred_data)
414  {
415  qof_query_destroy (tmp_q);
416  return;
417  }
418 
419  param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
420  qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
421  }
422 
423  qof_query_merge_in_place (q, tmp_q, op);
424  qof_query_destroy (tmp_q);
425 }
426 
427 void
428 xaccQueryGetDateMatchTT (QofQuery * q,
429  time64 * stt,
430  time64 * ett)
431 {
432  QofQueryPredData *term_data;
433  GSList *param_list;
434  GSList *terms, *tmp;
435 
436  *stt = 0;
437  *ett = 0;
438 
439  param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
440  terms = qof_query_get_term_type (q, param_list);
441  g_slist_free(param_list);
442 
443  for (tmp = terms; tmp; tmp = g_slist_next(tmp))
444  {
445  term_data = static_cast<QofQueryPredData*>(tmp->data);
446  if (term_data->how == QOF_COMPARE_GTE)
447  qof_query_date_predicate_get_date(term_data, stt);
448  if (term_data->how == QOF_COMPARE_LTE)
449  qof_query_date_predicate_get_date(term_data, ett);
450  }
451  g_slist_free(terms);
452 }
453 
454 /********************************************************************
455  * xaccQueryAddDateMatch
456  * Add a date filter to an existing query.
457  ********************************************************************/
458 
459 void
460 xaccQueryAddDateMatch(QofQuery * q,
461  gboolean use_start, int sday, int smonth, int syear,
462  gboolean use_end, int eday, int emonth, int eyear,
463  QofQueryOp op)
464 {
465  /* gcc -O3 will auto-inline this function, avoiding a call overhead */
466  xaccQueryAddDateMatchTT (q, use_start,
467  gnc_dmy2time64(sday, smonth, syear),
468  use_end,
469  gnc_dmy2time64_end(eday, emonth, eyear),
470  op);
471 }
472 
473 void
474 xaccQueryAddClearedMatch(QofQuery * q, cleared_match_t how, QofQueryOp op)
475 {
476  QofQueryPredData *pred_data;
477  GSList *param_list;
478  char chars[6];
479  int i = 0;
480 
481  if (!q)
482  return;
483 
484  if (how & CLEARED_CLEARED)
485  chars[i++] = CREC;
486  if (how & CLEARED_RECONCILED)
487  chars[i++] = YREC;
488  if (how & CLEARED_FROZEN)
489  chars[i++] = FREC;
490  if (how & CLEARED_NO)
491  chars[i++] = NREC;
492  if (how & CLEARED_VOIDED)
493  chars[i++] = VREC;
494  chars[i] = '\0';
495 
496  pred_data = qof_query_char_predicate (QOF_CHAR_MATCH_ANY, chars);
497  if (!pred_data)
498  return;
499 
500  param_list = qof_query_build_param_list (SPLIT_RECONCILE, nullptr);
501 
502  qof_query_add_term (q, param_list, pred_data, op);
503 }
504 
505 cleared_match_t
506 xaccQueryGetClearedMatch(QofQuery * q)
507 {
508  QofQueryPredData *term_data;
509  cleared_match_t cleared_match = CLEARED_ALL;
510  GSList *param_list;
511  GSList *terms, *tmp;
512  char *chars = nullptr;
513 
514  param_list = qof_query_build_param_list (SPLIT_RECONCILE, nullptr);
515  terms = qof_query_get_term_type (q, param_list);
516  g_slist_free (param_list);
517 
518  for (tmp = terms; tmp; tmp = g_slist_next (tmp))
519  {
520  term_data = static_cast<QofQueryPredData*>(tmp->data);
521 
522  if (qof_query_char_predicate_get_char (term_data, &chars))
523  {
524  cleared_match = CLEARED_NONE;
525 
526  if (strstr (chars, "c"))
527  cleared_match = (cleared_match_t)(cleared_match | CLEARED_CLEARED);
528  if (strstr (chars, "y"))
529  cleared_match = (cleared_match_t)(cleared_match | CLEARED_RECONCILED);
530  if (strstr (chars, "f"))
531  cleared_match = (cleared_match_t)(cleared_match | CLEARED_FROZEN);
532  if (strstr (chars, "n"))
533  cleared_match = (cleared_match_t)(cleared_match | CLEARED_NO);
534  if (strstr (chars, "v"))
535  cleared_match = (cleared_match_t)(cleared_match | CLEARED_VOIDED);
536  }
537  }
538  g_slist_free (terms);
539 
540  return cleared_match;
541 }
542 
543 void
544 xaccQueryAddGUIDMatch(QofQuery * q, const GncGUID *guid,
545  QofIdType id_type, QofQueryOp op)
546 {
547  GSList *param_list = nullptr;
548 
549  if (!q || !guid || !id_type)
550  return;
551 
552  if (!g_strcmp0 (id_type, GNC_ID_SPLIT))
553  param_list = qof_query_build_param_list (QOF_PARAM_GUID, nullptr);
554  else if (!g_strcmp0 (id_type, GNC_ID_TRANS))
555  param_list = qof_query_build_param_list (SPLIT_TRANS, QOF_PARAM_GUID, nullptr);
556  else if (!g_strcmp0 (id_type, GNC_ID_ACCOUNT))
557  param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID, nullptr);
558  else
559  PERR ("Invalid match type: %s", id_type);
560 
561  qof_query_add_guid_match (q, param_list, guid, op);
562 }
563 
564 
565 /********************************************************************
566  * xaccQueryAddClosingTransMatch
567  * Add a filter that matches book closing entries to an existing query.
568  ********************************************************************/
569 
570 void
571 xaccQueryAddClosingTransMatch(QofQuery *q, gboolean value, QofQueryOp op)
572 {
573  GSList *param_list;
574 
575  param_list = qof_query_build_param_list(SPLIT_TRANS, TRANS_IS_CLOSING, nullptr);
576  qof_query_add_boolean_match(q, param_list, value, op);
577 }
578 
579 /*******************************************************************
580  * xaccQueryGetEarliestDateFound
581  *******************************************************************/
582 
583 time64
584 xaccQueryGetEarliestDateFound(QofQuery * q)
585 {
586  GList * spl;
587  Split * sp;
588  time64 earliest;
589 
590  if (!q) return 0;
591  spl = qof_query_last_run (q);
592  if (!spl) return 0;
593 
594  /* Safe until 2038 on archs where time64 is 32bit */
595  sp = GNC_SPLIT (spl->data);
596  earliest = sp->parent->date_posted;
597  for (; spl; spl = spl->next)
598  {
599  sp = GNC_SPLIT (spl->data);
600  if (sp->parent->date_posted < earliest)
601  {
602  earliest = sp->parent->date_posted;
603  }
604  }
605  return earliest;
606 }
607 
608 /*******************************************************************
609  * xaccQueryGetLatestDateFound
610  *******************************************************************/
611 
612 time64
613 xaccQueryGetLatestDateFound(QofQuery * q)
614 {
615  Split * sp;
616  GList * spl;
617  time64 latest = 0;
618 
619  if (!q) return 0;
620  spl = qof_query_last_run (q);
621  if (!spl) return 0;
622 
623  for (; spl; spl = spl->next)
624  {
625  sp = GNC_SPLIT (spl->data);
626  if (sp->parent->date_posted > latest)
627  {
628  latest = sp->parent->date_posted;
629  }
630  }
631  return latest;
632 }
633 
634 void
635 xaccQueryAddDescriptionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
637 {
638  xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
639  TRANS_DESCRIPTION, nullptr);
640 }
641 
642 void
643 xaccQueryAddNotesMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
645 {
646  xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
647  TRANS_NOTES, nullptr);
648 }
649 
650 void
651 xaccQueryAddNumberMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
653 {
654  xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
655  TRANS_NUM, nullptr);
656 }
657 
658 void
659 xaccQueryAddActionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
661 {
662  xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_ACTION, nullptr);
663 }
664 
665 void
666 xaccQueryAddMemoMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
668 {
669  xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_MEMO, nullptr);
670 }
671 
672 void
673 xaccQueryAddValueMatch(QofQuery *q, gnc_numeric amt, QofNumericMatch sgn,
674  QofQueryCompare how, QofQueryOp op)
675 {
676  xaccQueryAddNumericMatch ((q), (amt), (sgn), (how), (op),
677  SPLIT_VALUE, nullptr);
678 }
679 
680 void
681 xaccQueryAddSharePriceMatch(QofQuery *q, gnc_numeric amt, QofQueryCompare how,
682  QofQueryOp op)
683 {
684  xaccQueryAddNumericMatch ((q), (amt), QOF_NUMERIC_MATCH_ANY, (how), (op),
685  SPLIT_SHARE_PRICE, nullptr);
686 }
687 
688 void
689 xaccQueryAddSharesMatch(QofQuery *q, gnc_numeric amt, QofQueryCompare how,
690  QofQueryOp op)
691 {
692  xaccQueryAddNumericMatch ((q), (amt), QOF_NUMERIC_MATCH_ANY, (how), (op),
693  SPLIT_AMOUNT, nullptr);
694 }
695 
696 void
697 xaccQueryAddBalanceMatch(QofQuery *q, QofQueryCompare bal, QofQueryOp op)
698 {
699  xaccQueryAddNumericMatch(
700  (q), gnc_numeric_zero(), QOF_NUMERIC_MATCH_ANY,
701  ((bal) ? QOF_COMPARE_EQUAL : QOF_COMPARE_NEQ), (op),
702  SPLIT_TRANS, TRANS_IMBALANCE, nullptr);
703 }
704 
705 
706 /* ======================== END OF FILE ======================= */
GList TransList
GList of Transaction.
Definition: gnc-engine.h:209
void qof_query_add_term(QofQuery *q, QofQueryParamList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
This is the general function that adds a new Query Term to a query.
Definition: qofquery.cpp:681
GList LotList
GList of GNCLots.
Definition: gnc-engine.h:205
STRUCTS.
time64 gnc_dmy2time64(gint day, gint month, gint year)
Convert a day, month, and year to a time64, returning the first second of the day.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
These expect a single object and expect the QofAccessFunc returns GncGUID*.
Definition: qofquerycore.h:113
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
#define VREC
split is void
Definition: Split.h:77
gboolean qof_query_date_predicate_get_date(const QofQueryPredData *pd, time64 *date)
Retrieve a predicate.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
const gchar * QofIdType
QofIdType declaration.
Definition: qofid.h:80
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
GList SplitList
GList of Split.
Definition: gnc-engine.h:207
Account handling public routines.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
QofGuidMatch
Definition: qofquerycore.h:109
#define YREC
The Split has been reconciled.
Definition: Split.h:74
#define FREC
frozen into accounting period
Definition: Split.h:75
#define SPLIT_ACCOUNT_GUID
for guid_match_all
Definition: Split.h:544
QofQueryCompare
Standard Query comparators, for how to compare objects in a predicate.
Definition: qofquerycore.h:54
const GncGUID * qof_entity_get_guid(gconstpointer ent)
These expect a GList* of objects and calls the QofAccessFunc routine on each item in the list to obta...
Definition: qofquerycore.h:118
#define CREC
The Split has been cleared.
Definition: Split.h:73
void qof_query_add_guid_match(QofQuery *q, QofQueryParamList *param_list, const GncGUID *guid, QofQueryOp op)
DOCUMENT ME !!
Definition: qofquery.cpp:1310
GList * qof_query_last_run(QofQuery *query)
Return the results of the last query, without causing the query to be re-run.
Definition: qofquery.cpp:897
QofQueryOp
Query Term Operators, for combining Query Terms.
Definition: qofquery.h:92
GList * qof_query_run(QofQuery *query)
Perform the query, return the results.
GList AccountList
GList of Account.
Definition: gnc-engine.h:203
time64 gnc_dmy2time64_end(gint day, gint month, gint year)
Same as gnc_dmy2time64, but last second of the day.
GList AccountGUIDList
GList of GUIDs of a Account.
Definition: gnc-engine.h:211
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition: gnc-date.h:87
void qof_query_add_boolean_match(QofQuery *q, QofQueryParamList *param_list, gboolean value, QofQueryOp op)
Handy-dandy convenience routines, avoids having to create a separate predicate for boolean matches...
Definition: qofquery.cpp:1347
API for Transactions and Splits (journal entries)
The type used to store guids in C.
Definition: guid.h:75
QofNumericMatch
Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED.
Definition: qofquerycore.h:101
QofQuery * qof_query_create(void)
Create a new query.
Definition: qofquery.cpp:918
A Query.
Definition: qofquery.cpp:74
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn&#39;t be...
Definition: Split.cpp:1886
#define NREC
not reconciled or cleared
Definition: Split.h:76
void qof_query_merge_in_place(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Like qof_query_merge, but this will merge a copy of q2 into q1.
Definition: qofquery.cpp:1236