GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-lot.c
1 /********************************************************************\
2  * gnc-lot.c -- AR/AP invoices; inventory lots; stock lots *
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 [email protected] *
20 \********************************************************************/
21 
22 /*
23  * FILE:
24  * gnc-lot.c
25  *
26  * FUNCTION:
27  * Lots implement the fundamental conceptual idea behind invoices,
28  * inventory lots, and stock market investment lots. See the file
29  * src/doc/lots.txt for implementation overview.
30  *
31  * XXX Lots are not currently treated in a correct transactional
32  * manner. There's now a per-Lot dirty flag in the QofInstance, but
33  * this code still needs to emit the correct signals when a lot has
34  * changed. This is true both in the Scrub2.c and in
35  * src/gnome/dialog-lot-viewer.c
36  *
37  * HISTORY:
38  * Created by Linas Vepstas May 2002
39  * Copyright (c) 2002,2003 Linas Vepstas <[email protected]>
40  */
41 
42 #include <config.h>
43 
44 #include <glib.h>
45 #include <glib/gi18n.h>
46 #include <qofinstance-p.h>
47 
48 #include "Account.h"
49 #include "AccountP.h"
50 #include "gnc-lot.h"
51 #include "gnc-lot-p.h"
52 #include "cap-gains.h"
53 #include "Transaction.h"
54 #include "TransactionP.h"
55 
56 /* This static indicates the debugging module that this .o belongs to. */
57 static QofLogModule log_module = GNC_MOD_LOT;
58 
59 struct gnc_lot_s
60 {
61  QofInstance inst;
62 };
63 
64 enum
65 {
66  PROP_0,
67 // PROP_ACCOUNT, /* Table */
68  PROP_IS_CLOSED, /* Table */
69 
70  PROP_INVOICE, /* KVP */
71  PROP_OWNER_TYPE, /* KVP */
72  PROP_OWNER_GUID, /* KVP */
73 
74  PROP_RUNTIME_0,
75  PROP_MARKER, /* Runtime */
76 };
77 
78 typedef struct LotPrivate
79 {
80  /* Account to which this lot applies. All splits in the lot must
81  * belong to this account.
82  */
83  Account * account;
84 
85  /* List of splits that belong to this lot. */
86  SplitList *splits;
87 
88  /* Handy cached value to indicate if lot is closed. */
89  /* If value is negative, then the cache is invalid. */
90  signed char is_closed;
91 #define LOT_CLOSED_UNKNOWN (-1)
92 
93  /* traversal marker, handy for preventing recursion */
94  unsigned char marker;
95 } LotPrivate;
96 
97 #define GET_PRIVATE(o) \
98  (G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_LOT, LotPrivate))
99 
100 #define gnc_lot_set_guid(L,G) qof_instance_set_guid(QOF_INSTANCE(L),&(G))
101 
102 /* ============================================================= */
103 
104 static void gnc_lot_set_invoice (GNCLot* lot, GncGUID *guid);
105 static GncGUID *gnc_lot_get_invoice (GNCLot* lot);
106 
107 /* ============================================================= */
108 
109 /* GObject Initialization */
110 G_DEFINE_TYPE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE)
111 
112 static void
113 gnc_lot_init(GNCLot* lot)
114 {
115  LotPrivate* priv;
116 
117  priv = GET_PRIVATE(lot);
118  priv->account = NULL;
119  priv->splits = NULL;
120  priv->is_closed = LOT_CLOSED_UNKNOWN;
121  priv->marker = 0;
122 }
123 
124 static void
125 gnc_lot_dispose(GObject *lotp)
126 {
127  G_OBJECT_CLASS(gnc_lot_parent_class)->dispose(lotp);
128 }
129 
130 static void
131 gnc_lot_finalize(GObject* lotp)
132 {
133  G_OBJECT_CLASS(gnc_lot_parent_class)->finalize(lotp);
134 }
135 
136 static void
137 gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
138 {
139  GNCLot* lot;
140  LotPrivate* priv;
141  KvpFrame *frame;
142  gchar *key;
143  GValue *temp;
144 
145  g_return_if_fail(GNC_IS_LOT(object));
146 
147  lot = GNC_LOT(object);
148  priv = GET_PRIVATE(lot);
149  switch (prop_id)
150  {
151  case PROP_IS_CLOSED:
152  g_value_set_int(value, priv->is_closed);
153  break;
154  case PROP_MARKER:
155  g_value_set_int(value, priv->marker);
156  break;
157  case PROP_INVOICE:
158  key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
159  qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
160  break;
161  case PROP_OWNER_TYPE:
162  key = GNC_OWNER_ID"/" GNC_OWNER_TYPE;
163  qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
164  break;
165  case PROP_OWNER_GUID:
166  key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
167  qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
168  break;
169  default:
170  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
171  break;
172  }
173 }
174 
175 static void
176 gnc_lot_set_property (GObject* object,
177  guint prop_id,
178  const GValue* value,
179  GParamSpec* pspec)
180 {
181  GNCLot* lot;
182  LotPrivate* priv;
183  KvpFrame *frame;
184  gchar *key = NULL;
185 
186  g_return_if_fail(GNC_IS_LOT(object));
187 
188  lot = GNC_LOT(object);
189  if (prop_id < PROP_RUNTIME_0)
190  g_assert (qof_instance_get_editlevel(lot));
191 
192  priv = GET_PRIVATE(lot);
193  switch (prop_id)
194  {
195  case PROP_IS_CLOSED:
196  priv->is_closed = g_value_get_int(value);
197  break;
198  case PROP_MARKER:
199  priv->marker = g_value_get_int(value);
200  break;
201  case PROP_INVOICE:
202  key = GNC_INVOICE_ID"/" GNC_INVOICE_GUID;
203  qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
204  break;
205  case PROP_OWNER_TYPE:
206  key = GNC_OWNER_ID "/" GNC_OWNER_TYPE;
207  qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
208  break;
209  case PROP_OWNER_GUID:
210  key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
211  qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
212  break;
213  default:
214  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
215  break;
216  }
217 }
218 
219 static void
220 gnc_lot_class_init(GNCLotClass* klass)
221 {
222  GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
223 
224  gobject_class->dispose = gnc_lot_dispose;
225  gobject_class->finalize = gnc_lot_finalize;
226  gobject_class->get_property = gnc_lot_get_property;
227  gobject_class->set_property = gnc_lot_set_property;
228 
229  g_type_class_add_private(klass, sizeof(LotPrivate));
230 
231  g_object_class_install_property(
232  gobject_class,
233  PROP_IS_CLOSED,
234  g_param_spec_int("is-closed",
235  "Is Lot Closed",
236  "Indication of whether this lot is open "
237  "or closed to further changes.",
238  -1, 1, 0,
239  G_PARAM_READWRITE));
240 
241  g_object_class_install_property(
242  gobject_class,
243  PROP_MARKER,
244  g_param_spec_int("marker",
245  "Lot marker",
246  "Ipsum Lorem",
247  0, G_MAXINT8, 0,
248  G_PARAM_READWRITE));
249 
250  g_object_class_install_property(
251  gobject_class,
252  PROP_INVOICE,
253  g_param_spec_boxed("invoice",
254  "Invoice attached to lot",
255  "Used by GncInvoice",
256  GNC_TYPE_GUID,
257  G_PARAM_READWRITE));
258 
259  g_object_class_install_property(
260  gobject_class,
261  PROP_OWNER_TYPE,
262  g_param_spec_int64("owner-type",
263  "Owning Entity Type of lot",
264  "Used by GncOwner",
265  0, G_MAXINT64, 0,
266  G_PARAM_READWRITE));
267 
268  g_object_class_install_property(
269  gobject_class,
270  PROP_OWNER_GUID,
271  g_param_spec_boxed("owner-guid",
272  "Owner attached to lot",
273  "Used by GncOwner",
274  GNC_TYPE_GUID,
275  G_PARAM_READWRITE));
276 }
277 
278 GNCLot *
279 gnc_lot_new (QofBook *book)
280 {
281  GNCLot *lot;
282  g_return_val_if_fail (book, NULL);
283 
284  lot = g_object_new (GNC_TYPE_LOT, NULL);
285  qof_instance_init_data(QOF_INSTANCE(lot), GNC_ID_LOT, book);
286  qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_CREATE, NULL);
287  return lot;
288 }
289 
290 static void
291 gnc_lot_free(GNCLot* lot)
292 {
293  GList *node;
294  LotPrivate* priv;
295  if (!lot) return;
296 
297  ENTER ("(lot=%p)", lot);
298  qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_DESTROY, NULL);
299 
300  priv = GET_PRIVATE(lot);
301  for (node = priv->splits; node; node = node->next)
302  {
303  Split *s = node->data;
304  s->lot = NULL;
305  }
306  g_list_free (priv->splits);
307 
308  priv->account = NULL;
309  priv->is_closed = TRUE;
310  /* qof_instance_release (&lot->inst); */
311  g_object_unref (lot);
312 
313  LEAVE();
314 }
315 
316 void
317 gnc_lot_destroy (GNCLot *lot)
318 {
319  if (!lot) return;
320 
321  gnc_lot_begin_edit(lot);
322  qof_instance_set_destroying(lot, TRUE);
323  gnc_lot_commit_edit(lot);
324 }
325 
326 /* ============================================================= */
327 
328 void
329 gnc_lot_begin_edit (GNCLot *lot)
330 {
331  qof_begin_edit(QOF_INSTANCE(lot));
332 }
333 
334 static void commit_err (QofInstance *inst, QofBackendError errcode)
335 {
336  PERR ("Failed to commit: %d", errcode);
337  gnc_engine_signal_commit_error( errcode );
338 }
339 
340 static void lot_free(QofInstance* inst)
341 {
342  GNCLot* lot = GNC_LOT(inst);
343 
344  gnc_lot_free(lot);
345 }
346 
347 static void noop (QofInstance *inst) {}
348 
349 void
350 gnc_lot_commit_edit (GNCLot *lot)
351 {
352  if (!qof_commit_edit (QOF_INSTANCE(lot))) return;
353  qof_commit_edit_part2 (QOF_INSTANCE(lot), commit_err, noop, lot_free);
354 }
355 
356 /* ============================================================= */
357 
358 GNCLot *
359 gnc_lot_lookup (const GncGUID *guid, QofBook *book)
360 {
361  QofCollection *col;
362  if (!guid || !book) return NULL;
363  col = qof_book_get_collection (book, GNC_ID_LOT);
364  return (GNCLot *) qof_collection_lookup_entity (col, guid);
365 }
366 
367 QofBook *
368 gnc_lot_get_book (GNCLot *lot)
369 {
370  return qof_instance_get_book(QOF_INSTANCE(lot));
371 }
372 
373 /* ============================================================= */
374 
375 gboolean
377 {
378  LotPrivate* priv;
379  if (!lot) return TRUE;
380  priv = GET_PRIVATE(lot);
381  if (0 > priv->is_closed) gnc_lot_get_balance (lot);
382  return priv->is_closed;
383 }
384 
385 Account *
387 {
388  LotPrivate* priv;
389  if (!lot) return NULL;
390  priv = GET_PRIVATE(lot);
391  return priv->account;
392 }
393 
394 void
395 gnc_lot_set_account(GNCLot* lot, Account* account)
396 {
397  if (lot != NULL)
398  {
399  LotPrivate* priv;
400  priv = GET_PRIVATE(lot);
401  priv->account = account;
402  }
403 }
404 
405 void
407 {
408  LotPrivate* priv;
409  if (lot != NULL)
410  {
411  priv = GET_PRIVATE(lot);
412  priv->is_closed = LOT_CLOSED_UNKNOWN;
413  }
414 }
415 
416 SplitList *
418 {
419  LotPrivate* priv;
420  if (!lot) return NULL;
421  priv = GET_PRIVATE(lot);
422  return priv->splits;
423 }
424 
425 gint gnc_lot_count_splits (const GNCLot *lot)
426 {
427  LotPrivate* priv;
428  if (!lot) return 0;
429  priv = GET_PRIVATE(lot);
430  return g_list_length (priv->splits);
431 }
432 
433 /* ============================================================== */
434 /* Hmm, we should probably inline these. */
435 
436 const char *
438 {
439  if (!lot) return NULL;
440  return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
441  "/title");
442 }
443 
444 const char *
445 gnc_lot_get_notes (const GNCLot *lot)
446 {
447  if (!lot) return NULL;
448  return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
449  "/notes");
450 }
451 
452 void
453 gnc_lot_set_title (GNCLot *lot, const char *str)
454 {
455  if (!lot) return;
456  qof_begin_edit(QOF_INSTANCE(lot));
457  qof_instance_set_dirty(QOF_INSTANCE(lot));
458  kvp_frame_set_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
459  "/title", str);
460  gnc_lot_commit_edit(lot);
461 }
462 
463 void
464 gnc_lot_set_notes (GNCLot *lot, const char *str)
465 {
466  if (!lot) return;
467  gnc_lot_begin_edit(lot);
468  qof_instance_set_dirty(QOF_INSTANCE(lot));
469  kvp_frame_set_string (qof_instance_get_slots (QOF_INSTANCE (lot)),
470  "/notes", str);
471  gnc_lot_commit_edit(lot);
472 }
473 
474 /* ============================================================= */
475 
478 {
479  LotPrivate* priv;
480  GList *node;
481  gnc_numeric zero = gnc_numeric_zero();
482  gnc_numeric baln = zero;
483  if (!lot) return zero;
484 
485  priv = GET_PRIVATE(lot);
486  if (!priv->splits)
487  {
488  priv->is_closed = FALSE;
489  return zero;
490  }
491 
492  /* Sum over splits; because they all belong to same account
493  * they will have same denominator.
494  */
495  for (node = priv->splits; node; node = node->next)
496  {
497  Split *s = node->data;
499  baln = gnc_numeric_add_fixed (baln, amt);
500  g_assert (gnc_numeric_check (baln) == GNC_ERROR_OK);
501  }
502 
503  /* cache a zero balance as a closed lot */
504  if (gnc_numeric_equal (baln, zero))
505  {
506  priv->is_closed = TRUE;
507  }
508  else
509  {
510  priv->is_closed = FALSE;
511  }
512 
513  return baln;
514 }
515 
516 /* ============================================================= */
517 
518 void
519 gnc_lot_get_balance_before (const GNCLot *lot, const Split *split,
520  gnc_numeric *amount, gnc_numeric *value)
521 {
522  LotPrivate* priv;
523  GList *node;
524  gnc_numeric zero = gnc_numeric_zero();
525  gnc_numeric amt = zero;
526  gnc_numeric val = zero;
527 
528  *amount = amt;
529  *value = val;
530  if (lot == NULL) return;
531 
532  priv = GET_PRIVATE(lot);
533  if (priv->splits)
534  {
535  Transaction *ta, *tb;
536  const Split *target;
537  /* If this is a gains split, find the source of the gains and use
538  its transaction for the comparison. Gains splits are in separate
539  transactions that may sort after non-gains transactions. */
540  target = xaccSplitGetGainsSourceSplit (split);
541  if (target == NULL)
542  target = split;
543  tb = xaccSplitGetParent (target);
544  for (node = priv->splits; node; node = node->next)
545  {
546  Split *s = node->data;
547  Split *source = xaccSplitGetGainsSourceSplit (s);
548  if (source == NULL)
549  source = s;
550  ta = xaccSplitGetParent (source);
551  if ((ta == tb && source != target) ||
552  xaccTransOrder (ta, tb) < 0)
553  {
554  gnc_numeric tmpval = xaccSplitGetAmount (s);
555  amt = gnc_numeric_add_fixed (amt, tmpval);
556  tmpval = xaccSplitGetValue (s);
557  val = gnc_numeric_add_fixed (val, tmpval);
558  }
559  }
560  }
561 
562  *amount = amt;
563  *value = val;
564 }
565 
566 /* ============================================================= */
567 
568 void
570 {
571  LotPrivate* priv;
572  Account * acc;
573  if (!lot || !split) return;
574  priv = GET_PRIVATE(lot);
575 
576  ENTER ("(lot=%p, split=%p) %s amt=%s val=%s", lot, split,
577  gnc_lot_get_title (lot),
578  gnc_num_dbg_to_string (split->amount),
579  gnc_num_dbg_to_string (split->value));
580  gnc_lot_begin_edit(lot);
581  acc = xaccSplitGetAccount (split);
582  qof_instance_set_dirty(QOF_INSTANCE(lot));
583  if (NULL == priv->account)
584  {
585  xaccAccountInsertLot (acc, lot);
586  }
587  else if (priv->account != acc)
588  {
589  PERR ("splits from different accounts cannot "
590  "be added to this lot!\n"
591  "\tlot account=\'%s\', split account=\'%s\'\n",
592  xaccAccountGetName(priv->account), xaccAccountGetName (acc));
593  gnc_lot_commit_edit(lot);
594  LEAVE("different accounts");
595  return;
596  }
597 
598  if (lot == split->lot)
599  {
600  gnc_lot_commit_edit(lot);
601  LEAVE("already in lot");
602  return; /* handle not-uncommon no-op */
603  }
604  if (split->lot)
605  {
606  gnc_lot_remove_split (split->lot, split);
607  }
608  xaccSplitSetLot(split, lot);
609 
610  priv->splits = g_list_append (priv->splits, split);
611 
612  /* for recomputation of is-closed */
613  priv->is_closed = LOT_CLOSED_UNKNOWN;
614  gnc_lot_commit_edit(lot);
615 
616  qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL);
617  LEAVE("added to lot");
618 }
619 
620 void
621 gnc_lot_remove_split (GNCLot *lot, Split *split)
622 {
623  LotPrivate* priv;
624  if (!lot || !split) return;
625  priv = GET_PRIVATE(lot);
626 
627  ENTER ("(lot=%p, split=%p)", lot, split);
628  gnc_lot_begin_edit(lot);
629  qof_instance_set_dirty(QOF_INSTANCE(lot));
630  priv->splits = g_list_remove (priv->splits, split);
631  xaccSplitSetLot(split, NULL);
632  priv->is_closed = LOT_CLOSED_UNKNOWN; /* force an is-closed computation */
633 
634  if (NULL == priv->splits)
635  {
636  xaccAccountRemoveLot (priv->account, lot);
637  priv->account = NULL;
638  }
639  gnc_lot_commit_edit(lot);
640  qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL);
641  LEAVE("removed from lot");
642 }
643 
644 /* ============================================================== */
645 /* Utility function, get earliest split in lot */
646 
647 Split *
649 {
650  LotPrivate* priv;
651  if (!lot) return NULL;
652  priv = GET_PRIVATE(lot);
653  if (! priv->splits) return NULL;
654  priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly);
655  return priv->splits->data;
656 }
657 
658 /* Utility function, get latest split in lot */
659 Split *
661 {
662  LotPrivate* priv;
663  SplitList *node;
664 
665  if (!lot) return NULL;
666  priv = GET_PRIVATE(lot);
667  if (! priv->splits) return NULL;
668  priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly);
669 
670  for (node = priv->splits; node->next; node = node->next)
671  ;
672 
673  return node->data;
674 }
675 
676 /* ============================================================= */
677 
678 static void
679 destroy_lot_on_book_close(QofInstance *ent, gpointer data)
680 {
681  GNCLot* lot = GNC_LOT(ent);
682 
683  gnc_lot_destroy(lot);
684 }
685 
686 static void
687 gnc_lot_book_end(QofBook* book)
688 {
689  QofCollection *col;
690 
691  col = qof_book_get_collection(book, GNC_ID_LOT);
692  qof_collection_foreach(col, destroy_lot_on_book_close, NULL);
693 }
694 
695 #ifdef _MSC_VER
696 /* MSVC compiler doesn't have C99 "designated initializers"
697  * so we wrap them in a macro that is empty on MSVC. */
698 # define DI(x) /* */
699 #else
700 # define DI(x) x
701 #endif
702 static QofObject gncLotDesc =
703 {
704  DI(.interface_version = ) QOF_OBJECT_VERSION,
705  DI(.e_type = ) GNC_ID_LOT,
706  DI(.type_label = ) "Lot",
707  DI(.create = ) (gpointer)gnc_lot_new,
708  DI(.book_begin = ) NULL,
709  DI(.book_end = ) gnc_lot_book_end,
710  DI(.is_dirty = ) qof_collection_is_dirty,
711  DI(.mark_clean = ) qof_collection_mark_clean,
712  DI(.foreach = ) qof_collection_foreach,
713  DI(.printable = ) NULL,
714  DI(.version_cmp = ) (int (*)(gpointer, gpointer))qof_instance_version_cmp,
715 };
716 
717 
718 gboolean gnc_lot_register (void)
719 {
720  static const QofParam params[] =
721  {
722  {
723  LOT_TITLE, QOF_TYPE_STRING,
725  (QofSetterFunc) gnc_lot_set_title
726  },
727  {
728  LOT_NOTES, QOF_TYPE_STRING,
729  (QofAccessFunc) gnc_lot_get_notes,
730  (QofSetterFunc) gnc_lot_set_notes
731  },
732  {
733  QOF_PARAM_GUID, QOF_TYPE_GUID,
735  },
736  {
737  QOF_PARAM_BOOK, QOF_ID_BOOK,
738  (QofAccessFunc) gnc_lot_get_book, NULL
739  },
740  {
741  LOT_IS_CLOSED, QOF_TYPE_BOOLEAN,
743  },
744  {
745  LOT_BALANCE, QOF_TYPE_NUMERIC,
747  },
748  { NULL },
749  };
750 
751  qof_class_register (GNC_ID_LOT, NULL, params);
752  return qof_object_register(&gncLotDesc);
753 }
754 
756 {
757  GNCLot * lot;
758  gint64 id = 0;
759  gchar *buff;
760 
761  lot = gnc_lot_new (qof_instance_get_book(acc));
762 
763  /* Provide a reasonable title for the new lot */
764  xaccAccountBeginEdit (acc);
765  qof_instance_get (QOF_INSTANCE (acc), "lot-next-id", &id, NULL);
766  buff = g_strdup_printf ("%s %" G_GINT64_FORMAT, _("Lot"), id);
767  gnc_lot_set_title (lot, buff);
768  id ++;
769  qof_instance_set (QOF_INSTANCE (acc), "lot-next-id", id, NULL);
770  xaccAccountCommitEdit (acc);
771  g_free (buff);
772  return lot;
773 }
774 
775 /* ========================== END OF FILE ========================= */
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
gchar * gnc_num_dbg_to_string(gnc_numeric n)
void qof_instance_get(const QofInstance *inst, const gchar *first_param,...)
Wrapper for g_object_get.
QofBook * qof_instance_get_book(gconstpointer)
gboolean qof_collection_is_dirty(const QofCollection *col)
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:59
void qof_instance_set(QofInstance *inst, const gchar *first_param,...)
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_fcn, const QofParam *params)
void gnc_lot_add_split(GNCLot *lot, Split *split)
Definition: gnc-lot.c:569
Split * xaccSplitGetGainsSourceSplit(const Split *split)
Definition: cap-gains.c:514
void xaccAccountInsertLot(Account *acc, GNCLot *lot)
Definition: Account.c:1920
Transaction * xaccSplitGetParent(const Split *split)
Definition: Split.c:1903
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:177
#define QOF_OBJECT_VERSION
Definition: qofobject.h:64
gboolean qof_commit_edit(QofInstance *inst)
#define PERR(format, args...)
Definition: qoflog.h:237
#define ENTER(format, args...)
Definition: qoflog.h:261
#define QOF_PARAM_BOOK
Definition: qofquery.h:109
void gnc_lot_set_closed_unknown(GNCLot *lot)
Definition: gnc-lot.c:406
void qof_collection_foreach(const QofCollection *, QofInstanceForeachCB, gpointer user_data)
Split * gnc_lot_get_earliest_split(GNCLot *lot)
Definition: gnc-lot.c:648
Definition: guid.h:65
const char * gnc_lot_get_title(const GNCLot *lot)
Definition: gnc-lot.c:437
Split * gnc_lot_get_latest_split(GNCLot *lot)
Definition: gnc-lot.c:660
void qof_instance_init_data(QofInstance *, QofIdType, QofBook *)
gboolean qof_begin_edit(QofInstance *inst)
GList SplitList
Definition: gnc-engine.h:203
Account handling public routines.
SplitList * gnc_lot_get_split_list(const GNCLot *lot)
Definition: gnc-lot.c:417
void gnc_lot_get_balance_before(const GNCLot *lot, const Split *split, gnc_numeric *amount, gnc_numeric *value)
Definition: gnc-lot.c:519
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
void qof_collection_mark_clean(QofCollection *)
#define GNC_INVOICE_ID
Definition: gnc-engine.h:257
const GncGUID * qof_entity_get_guid(gconstpointer)
void xaccSplitSetLot(Split *split, GNCLot *lot)
Definition: Split.c:1959
GNCLot * gnc_lot_make_default(Account *acc)
Definition: gnc-lot.c:755
gboolean gnc_lot_is_closed(GNCLot *lot)
Definition: gnc-lot.c:376
Definition: SplitP.h:71
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
void xaccAccountBeginEdit(Account *acc)
Definition: Account.c:1280
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
#define LEAVE(format, args...)
Definition: qoflog.h:271
void(* QofSetterFunc)(gpointer, gpointer)
Definition: qofclass.h:184
int xaccTransOrder(const Transaction *ta, const Transaction *tb)
Definition: Transaction.c:1827
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
Account * gnc_lot_get_account(const GNCLot *lot)
Definition: gnc-lot.c:386
gboolean qof_object_register(const QofObject *object)
const char * xaccAccountGetName(const Account *acc)
Definition: Account.c:3031
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
API for Transactions and Splits (journal entries)
void xaccAccountCommitEdit(Account *acc)
Definition: Account.c:1321
Utilities to Automatically Compute Capital Gains/Losses.
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
gnc_numeric gnc_lot_get_balance(GNCLot *lot)
Definition: gnc-lot.c:477
const gchar * QofLogModule
Definition: qofid.h:89
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987