45 #include <glib/gi18n.h>    46 #include <qofinstance-p.h>    51 #include "gnc-lot-p.h"    54 #include "TransactionP.hpp"    58 static QofLogModule log_module = GNC_MOD_LOT;
    92     GncInvoice *cached_invoice;
    95     signed char is_closed;
    96 #define LOT_CLOSED_UNKNOWN (-1)   102 #define GET_PRIVATE(o) \   103     ((GNCLotPrivate*)gnc_lot_get_instance_private((GNCLot*)o))   105 #define gnc_lot_set_guid(L,G)  qof_instance_set_guid(QOF_INSTANCE(L),&(G))   110 G_DEFINE_TYPE_WITH_PRIVATE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE)
   113 gnc_lot_init(GNCLot* lot)
   117     priv = GET_PRIVATE(lot);
   118     priv->account = 
nullptr;
   119     priv->splits = 
nullptr;
   120     priv->cached_invoice = 
nullptr;
   121     priv->is_closed = LOT_CLOSED_UNKNOWN;
   126 gnc_lot_dispose(GObject *lotp)
   128     G_OBJECT_CLASS(gnc_lot_parent_class)->dispose(lotp);
   132 gnc_lot_finalize(GObject* lotp)
   134     G_OBJECT_CLASS(gnc_lot_parent_class)->finalize(lotp);
   138 gnc_lot_get_property(GObject* 
object, guint prop_id, GValue* value, GParamSpec* pspec)
   143     g_return_if_fail(GNC_IS_LOT(
object));
   145     lot = GNC_LOT(
object);
   146     priv = GET_PRIVATE(lot);
   150         g_value_set_int(value, priv->is_closed);
   153         g_value_set_int(value, priv->marker);
   158     case PROP_OWNER_TYPE:
   161     case PROP_OWNER_GUID:
   165         G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
   171 gnc_lot_set_property (GObject* 
object,
   179     g_return_if_fail(GNC_IS_LOT(
object));
   181     lot = GNC_LOT(
object);
   182     if (prop_id < PROP_RUNTIME_0)
   183         g_assert (qof_instance_get_editlevel(lot));
   185     priv = GET_PRIVATE(lot);
   189         priv->is_closed = g_value_get_int(value);
   192         priv->marker = g_value_get_int(value);
   197     case PROP_OWNER_TYPE:
   200     case PROP_OWNER_GUID:
   204         G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
   210 gnc_lot_class_init(GNCLotClass* klass)
   212     GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
   214     gobject_class->dispose = gnc_lot_dispose;
   215     gobject_class->finalize = gnc_lot_finalize;
   216     gobject_class->get_property = gnc_lot_get_property;
   217     gobject_class->set_property = gnc_lot_set_property;
   219     g_object_class_install_property(
   222         g_param_spec_int(
"is-closed",
   224                          "Indication of whether this lot is open "   225                          "or closed to further changes.",
   229     g_object_class_install_property(
   232         g_param_spec_int(
"marker",
   238      g_object_class_install_property(
   241         g_param_spec_boxed(
"invoice",
   242                            "Invoice attached to lot",
   243                            "Used by GncInvoice",
   247      g_object_class_install_property(
   250         g_param_spec_int64(
"owner-type",
   251                            "Owning Entity Type of  lot",
   256      g_object_class_install_property(
   259         g_param_spec_boxed(
"owner-guid",
   260                            "Owner attached to lot",
   267 gnc_lot_new (QofBook *book)
   270     g_return_val_if_fail (book, 
nullptr);
   272     lot = GNC_LOT(g_object_new (GNC_TYPE_LOT, 
nullptr));
   274     qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_CREATE, 
nullptr);
   279 gnc_lot_free(GNCLot* lot)
   285     ENTER (
"(lot=%p)", lot);
   286     qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_DESTROY, 
nullptr);
   288     priv = GET_PRIVATE(lot);
   289     for (node = priv->splits; node; node = node->next)
   291         Split *s = GNC_SPLIT(node->data);
   294     g_list_free (priv->splits);
   297         xaccAccountRemoveLot (priv->account, lot);
   299     priv->account = 
nullptr;
   300     priv->is_closed = TRUE;
   302     g_object_unref (lot);
   308 gnc_lot_destroy (GNCLot *lot)
   312     gnc_lot_begin_edit(lot);
   313     qof_instance_set_destroying(lot, TRUE);
   314     gnc_lot_commit_edit(lot);
   320 gnc_lot_begin_edit (GNCLot *lot)
   327     PERR (
"Failed to commit: %d", errcode);
   328     gnc_engine_signal_commit_error( errcode );
   333     GNCLot* lot = GNC_LOT(inst);
   341 gnc_lot_commit_edit (GNCLot *lot)
   350 gnc_lot_lookup (
const GncGUID *guid, QofBook *book)
   353     if (!guid || !book) 
return nullptr;
   359 gnc_lot_get_book (GNCLot *lot)
   370     if (!lot) 
return TRUE;
   371     priv = GET_PRIVATE(lot);
   373     return priv->is_closed;
   380     if (!lot) 
return nullptr;
   381     priv = GET_PRIVATE(lot);
   382     return priv->account;
   387      if (!lot) 
return nullptr;
   391          return priv->cached_invoice;
   396 gnc_lot_set_cached_invoice(GNCLot* lot, GncInvoice *invoice)
   399     GET_PRIVATE(lot)->cached_invoice = invoice;
   403 gnc_lot_set_account(GNCLot* lot, 
Account* account)
   408         priv = GET_PRIVATE(lot);
   409         priv->account = account;
   419         priv = GET_PRIVATE(lot);
   420         priv->is_closed = LOT_CLOSED_UNKNOWN;
   428     if (!lot) 
return nullptr;
   429     priv = GET_PRIVATE(lot);
   433 gint gnc_lot_count_splits (
const GNCLot *lot)
   437     priv = GET_PRIVATE(lot);
   438     return g_list_length (priv->splits);
   445 gnc_lot_get_title (
const GNCLot *lot)
   447     if (!lot) 
return nullptr;
   449     auto str{qof_instance_get_path_kvp<const char*> (QOF_INSTANCE (lot), {
"title"})};
   450     return str ? *str : 
nullptr;
   454 gnc_lot_get_notes (
const GNCLot *lot)
   456     if (!lot) 
return nullptr;
   458     auto str{qof_instance_get_path_kvp<const char*> (QOF_INSTANCE (lot), {
"notes"})};
   459     return str ? *str : 
nullptr;
   463 gnc_lot_set_title (GNCLot *lot, 
const char *str)
   468     qof_instance_set_path_kvp<const char*> (QOF_INSTANCE (lot), g_strdup(str), {
"title"});
   469     qof_instance_set_dirty(QOF_INSTANCE(lot));
   470     gnc_lot_commit_edit(lot);
   474 gnc_lot_set_notes (GNCLot *lot, 
const char *str)
   479     qof_instance_set_path_kvp<const char*> (QOF_INSTANCE (lot), g_strdup(str), {
"notes"});
   480     qof_instance_set_dirty(QOF_INSTANCE(lot));
   481     gnc_lot_commit_edit(lot);
   491     gnc_numeric zero = gnc_numeric_zero();
   492     gnc_numeric baln = zero;
   493     if (!lot) 
return zero;
   495     priv = GET_PRIVATE(lot);
   498         priv->is_closed = FALSE;
   505     for (node = priv->splits; node; node = node->next)
   507         Split *s = GNC_SPLIT(node->data);
   509         baln = gnc_numeric_add_fixed (baln, amt);
   516         priv->is_closed = TRUE;
   520         priv->is_closed = FALSE;
   530                             gnc_numeric *amount, gnc_numeric *value)
   534     gnc_numeric zero = gnc_numeric_zero();
   535     gnc_numeric amt = zero;
   536     gnc_numeric val = zero;
   540     if (lot == 
nullptr) 
return;
   542     priv = GET_PRIVATE(lot);
   545         Transaction *ta, *tb;
   551         if (target == 
nullptr)
   554         for (node = priv->splits; node; node = node->next)
   556             Split *s = GNC_SPLIT(node->data);
   558             if (source == 
nullptr)
   561             if ((ta == tb && source != target) ||
   565                 amt = gnc_numeric_add_fixed (amt, tmpval);
   567                 val = gnc_numeric_add_fixed (val, tmpval);
   583     if (!lot || !split) 
return;
   584     priv = GET_PRIVATE(lot);
   586     ENTER (
"(lot=%p, split=%p) %s amt=%s val=%s", lot, split,
   587            gnc_lot_get_title (lot),
   590     gnc_lot_begin_edit(lot);
   592     qof_instance_set_dirty(QOF_INSTANCE(lot));
   593     if (
nullptr == priv->account)
   597     else if (priv->account != acc)
   599         PERR (
"splits from different accounts cannot "   600               "be added to this lot!\n"   601               "\tlot account=\'%s\', split account=\'%s\'\n",
   603         gnc_lot_commit_edit(lot);
   604         LEAVE(
"different accounts");
   608     if (lot == split->lot)
   610         gnc_lot_commit_edit(lot);
   611         LEAVE(
"already in lot");
   620     priv->splits = g_list_append (priv->splits, split);
   623     priv->is_closed = LOT_CLOSED_UNKNOWN;
   624     gnc_lot_commit_edit(lot);
   626     qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, 
nullptr);
   627     LEAVE(
"added to lot");
   634     if (!lot || !split) 
return;
   635     priv = GET_PRIVATE(lot);
   637     ENTER (
"(lot=%p, split=%p)", lot, split);
   638     gnc_lot_begin_edit(lot);
   639     qof_instance_set_dirty(QOF_INSTANCE(lot));
   640     priv->splits = g_list_remove (priv->splits, split);
   642     priv->is_closed = LOT_CLOSED_UNKNOWN;   
   644     if (!priv->splits && priv->account)
   646         xaccAccountRemoveLot (priv->account, lot);
   647         priv->account = 
nullptr;
   649     gnc_lot_commit_edit(lot);
   650     qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, 
nullptr);
   651     LEAVE(
"removed from lot");
   661     if (!lot) 
return nullptr;
   662     priv = GET_PRIVATE(lot);
   663     if (! priv->splits) 
return nullptr;
   664     priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly);
   665     return GNC_SPLIT(priv->splits->data);
   675     if (!lot) 
return nullptr;
   676     priv = GET_PRIVATE(lot);
   677     if (! priv->splits) 
return nullptr;
   678     priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly);
   680     for (node = priv->splits; node->next; node = node->next)
   683     return GNC_SPLIT(node->data);
   689 destroy_lot_on_book_close(
QofInstance *ent, gpointer data)
   691     GNCLot* lot = GNC_LOT(ent);
   693     gnc_lot_destroy(lot);
   697 gnc_lot_book_end(QofBook* book)
   702     qof_collection_foreach(col, destroy_lot_on_book_close, 
nullptr);
   712 static QofObject gncLotDesc =
   715     DI(.e_type            = ) GNC_ID_LOT,
   716     DI(.type_label        = ) "Lot",
   717     DI(.create            = ) (
void* (*)(QofBook*))gnc_lot_new,
   718     DI(.book_begin        = ) 
nullptr,
   719     DI(.book_end          = ) gnc_lot_book_end,
   722     DI(.foreach           = ) qof_collection_foreach,
   723     DI(.printable         = ) 
nullptr,
   728 gboolean gnc_lot_register (
void)
   730     static const QofParam params[] =
   733             LOT_TITLE, QOF_TYPE_STRING,
   738             LOT_NOTES, QOF_TYPE_STRING,
   743             QOF_PARAM_GUID, QOF_TYPE_GUID,
   751             LOT_IS_CLOSED, QOF_TYPE_BOOLEAN,
   755             LOT_BALANCE, QOF_TYPE_NUMERIC,
   776     buff = g_strdup_printf (
"%s %" G_GINT64_FORMAT, _(
"Lot"), 
id);
   777     gnc_lot_set_title (lot, buff);
 int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times. 
This is the private header for the account structure. 
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number. 
gchar * gnc_num_dbg_to_string(gnc_numeric n)
Convert to string. 
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get. 
void qof_instance_set_kvp(QofInstance *, GValue const *value, unsigned count,...)
Sets a KVP slot to a value from a GValue. 
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer. 
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of 'dirty' flag on collection. 
QofInstance * qof_collection_lookup_entity(const QofCollection *col, const GncGUID *guid)
Find the entity going only from its guid. 
GncInvoice * gnc_lot_get_cached_invoice(const GNCLot *lot)
Returns the invoice with which this lot is associated. 
QofBackendError
The errors that can be reported to the GUI & other front-end users. 
Identifies that something sold at one time was bought at another. 
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed. 
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. 
void gnc_lot_add_split(GNCLot *lot, Split *split)
Adds a split to this lot. 
Split * xaccSplitGetGainsSourceSplit(const Split *split)
The xaccSplitGetGainsSourceSplit() routine returns the split that is the source of the cap gains in t...
void xaccAccountInsertLot(Account *acc, GNCLot *lot)
The xaccAccountInsertLot() method will register the indicated lot with this account. 
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split. 
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface. 
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers 
#define PERR(format, args...)
Log a serious error. 
#define ENTER(format, args...)
Print a function entry debugging message. 
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these 
void gnc_lot_set_closed_unknown(GNCLot *lot)
Reset closed flag so that it will be recalculated. 
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters. 
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue. 
Split * gnc_lot_get_earliest_split(GNCLot *lot)
Convenience routine to identify the earliest date in the lot. 
Split * gnc_lot_get_latest_split(GNCLot *lot)
Convenience routineto identify the date this lot was closed. 
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 
GList SplitList
GList of Split. 
Account handling public routines. 
SplitList * gnc_lot_get_split_list(const GNCLot *lot)
Returns a list of all the splits in this lot. 
void gnc_lot_remove_split(GNCLot *lot, Split *split)
Adds a split from this lot. 
void gnc_lot_get_balance_before(const GNCLot *lot, const Split *split, gnc_numeric *amount, gnc_numeric *value)
Computes both the balance and value in the lot considering only splits in transactions prior to the o...
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. 
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag 
#define GNC_INVOICE_ID
STRING CONSTANTS ********************************************** Used to declare constant KVP keys use...
const GncGUID * qof_entity_get_guid(gconstpointer ent)
void xaccSplitSetLot(Split *split, GNCLot *lot)
Assigns the split to a specific Lot. 
Business Invoice Interface. 
GNCLot * gnc_lot_make_default(Account *acc)
gboolean gnc_lot_is_closed(GNCLot *lot)
Returns closed status of the given lot. 
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity. 
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit(). 
#define LEAVE(format, args...)
Print a function exit debugging message. 
int xaccTransOrder(const Transaction *ta, const Transaction *tb)
The xaccTransOrder(ta,tb) method is useful for sorting. 
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
Check for error signal in value. 
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type. 
Account * gnc_lot_get_account(const GNCLot *lot)
Returns the account with which this lot is associated. 
gboolean qof_object_register(const QofObject *object)
Register new types of object objects. 
const char * xaccAccountGetName(const Account *acc)
Get the account's name. 
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments. 
API for Transactions and Splits (journal entries) 
The type used to store guids in C. 
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Utilities to Automatically Compute Capital Gains/Losses. 
gnc_numeric gnc_lot_get_balance(GNCLot *lot)
Returns the lot balance. 
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.