34 #include <glib/gi18n.h>    35 #include <qofinstance-p.h>    39 #include "gncBillTermP.h"    41 #include "gncEntryP.h"    45 #include "gncInvoiceP.h"    46 #include "gncOwnerP.h"    47 #include "engine-helpers.h"    57     const char    *billing_id;
    68     gnc_numeric   to_charge_amount;
    70     gnc_commodity *currency;
    73     Transaction   *posted_txn;
    79     QofInstanceClass parent_class;
    82 static QofLogModule log_module = GNC_MOD_BUSINESS;
    84 #define _GNC_MOD_NAME     GNC_ID_INVOICE    86 #define GNC_INVOICE_IS_CN "credit-note"    87 #define GNC_INVOICE_DOCLINK "assoc_uri" // this is the old name for the document link, kept for compatibility    89 #define SET_STR(obj, member, str) { \    90     if (!g_strcmp0 (member, str)) return; \    91     gncInvoiceBeginEdit (obj); \    92     CACHE_REPLACE (member, str); \    95 static void mark_invoice (GncInvoice *invoice);
    97 mark_invoice (GncInvoice *invoice)
    99     qof_instance_set_dirty (&invoice->inst);
   103 QofBook * gncInvoiceGetBook (GncInvoice *x)
   132 G_DEFINE_TYPE(GncInvoice, gnc_invoice, QOF_TYPE_INSTANCE)
   135 gnc_invoice_init (GncInvoice* inv)
   137     inv->date_posted = INT64_MAX;
   138     inv->date_opened = INT64_MAX;
   142 gnc_invoice_dispose (GObject *invp)
   144     G_OBJECT_CLASS(gnc_invoice_parent_class)->dispose(invp);
   148 gnc_invoice_finalize (GObject* invp)
   150     G_OBJECT_CLASS(gnc_invoice_parent_class)->finalize(invp);
   154 gnc_invoice_get_property (GObject         *
object,
   161     g_return_if_fail (GNC_IS_INVOICE(
object));
   163     inv = GNC_INVOICE(
object);
   167         g_value_set_string (value, inv->notes);
   170         G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
   176 gnc_invoice_set_property (GObject         *
object,
   183     g_return_if_fail (GNC_IS_INVOICE(
object));
   185     inv = GNC_INVOICE(
object);
   186     g_assert (qof_instance_get_editlevel (inv));
   191         gncInvoiceSetNotes (inv, g_value_get_string (value));
   194         G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
   207     g_return_val_if_fail (inst != NULL, FALSE);
   208     g_return_val_if_fail (GNC_IS_INVOICE(inst), FALSE);
   210     inv = GNC_INVOICE(inst);
   217         s = g_strdup_printf (
"Invoice %s (%s)", inv->id, display_name);
   218         g_free (display_name);
   222         s = g_strdup_printf (
"Invoice %s", inv->id);
   234     g_return_val_if_fail (inst != NULL, FALSE);
   235     g_return_val_if_fail (GNC_IS_INVOICE(inst), FALSE);
   237     inv = GNC_INVOICE(inst);
   239     if (GNC_IS_BILLTERM(ref))
   241         return (inv->terms == GNC_BILLTERM(ref));
   243     else if (GNC_IS_JOB(ref))
   245         return (inv->job == GNC_JOB(ref));
   247     else if (GNC_IS_COMMODITY(ref))
   249         return (inv->currency == GNC_COMMODITY(ref));
   251     else if (GNC_IS_ACCOUNT(ref))
   253         return (inv->posted_acc == GNC_ACCOUNT(ref));
   255     else if (GNC_IS_TRANSACTION(ref))
   257         return (inv->posted_txn == GNC_TRANSACTION(ref));
   259     else if (GNC_IS_LOT(ref))
   261         return (inv->posted_lot == GNC_LOT(ref));
   276     if (!GNC_IS_BILLTERM(ref) && !GNC_IS_JOB(ref) && !GNC_IS_COMMODITY(ref) && !GNC_IS_ACCOUNT(ref)
   277             && !GNC_IS_TRANSACTION(ref) && !GNC_IS_LOT(ref))
   286 gnc_invoice_class_init (GncInvoiceClass *klass)
   288     GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
   289     QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
   291     gobject_class->dispose = gnc_invoice_dispose;
   292     gobject_class->finalize = gnc_invoice_finalize;
   293     gobject_class->set_property = gnc_invoice_set_property;
   294     gobject_class->get_property = gnc_invoice_get_property;
   296     qof_class->get_display_name = impl_get_display_name;
   297     qof_class->refers_to_object = impl_refers_to_object;
   298     qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
   300     g_object_class_install_property
   303      g_param_spec_string (
"notes",
   305                           "The invoice notes is an arbitrary string "   306                           "assigned by the user to provide notes regarding "   313 GncInvoice *gncInvoiceCreate (QofBook *book)
   317     if (!book) 
return NULL;
   319     invoice = g_object_new (GNC_TYPE_INVOICE, NULL);
   322     invoice->id = CACHE_INSERT (
"");
   323     invoice->notes = CACHE_INSERT (
"");
   324     invoice->billing_id = CACHE_INSERT (
"");
   326     invoice->billto.type = GNC_OWNER_CUSTOMER;
   327     invoice->active = TRUE;
   329     invoice->to_charge_amount = gnc_numeric_zero ();
   341     GValue v = G_VALUE_INIT;
   347     invoice = g_object_new (GNC_TYPE_INVOICE, NULL);
   350     gncInvoiceBeginEdit (invoice);
   352     invoice->id = CACHE_INSERT (from->id);
   353     invoice->notes = CACHE_INSERT (from->notes);
   354     invoice->billing_id = CACHE_INSERT (from->billing_id);
   355     invoice->active = from->active;
   358     if (G_VALUE_HOLDS_INT64 (&v))
   362     invoice->terms = from->terms;
   363     gncBillTermIncRef (invoice->terms);
   365     gncOwnerCopy (&from->billto, &invoice->billto);
   366     gncOwnerCopy (&from->owner, &invoice->owner);
   367     invoice->job = from->job; 
   369     invoice->to_charge_amount = from->to_charge_amount;
   370     invoice->date_opened = from->date_opened;
   373     invoice->currency = from->currency;
   375     gncInvoiceSetDocLink (invoice, gncInvoiceGetDocLink (from));
   378     for (node = from->entries; node; node = node->next)
   380         GncEntry *from_entry = node->data;
   381         GncEntry *to_entry = gncEntryCreate (book);
   382         gncEntryCopy (from_entry, to_entry, FALSE);
   384         switch (gncInvoiceGetOwnerType (invoice))
   386         case GNC_OWNER_VENDOR:
   387         case GNC_OWNER_EMPLOYEE:
   391         case GNC_OWNER_CUSTOMER:
   394             gncInvoiceAddEntry (invoice, to_entry);
   403     mark_invoice (invoice);
   404     gncInvoiceCommitEdit (invoice);
   409 void gncInvoiceDestroy (GncInvoice *invoice)
   411     if (!invoice) 
return;
   412     qof_instance_set_destroying (invoice, TRUE);
   413     gncInvoiceCommitEdit (invoice);
   416 static void gncInvoiceFree (GncInvoice *invoice)
   418     if (!invoice) 
return;
   422     CACHE_REMOVE (invoice->id);
   423     CACHE_REMOVE (invoice->notes);
   424     CACHE_REMOVE (invoice->billing_id);
   425     g_list_free (invoice->entries);
   426     g_list_free (invoice->prices);
   428     if (invoice->printname)
   429         g_free (invoice->printname);
   434             gncBillTermDecRef (invoice->terms);
   438     g_object_unref (invoice);
   444 void gncInvoiceSetID (GncInvoice *invoice, 
const char *
id)
   446     if (!invoice || !
id) 
return;
   447     SET_STR (invoice, invoice->id, 
id);
   448     mark_invoice (invoice);
   449     gncInvoiceCommitEdit (invoice);
   452 void gncInvoiceSetOwner (GncInvoice *invoice, 
GncOwner *owner)
   454     if (!invoice || !owner) 
return;
   456     gncInvoiceBeginEdit (invoice);
   457     gncOwnerCopy (owner, &invoice->owner);
   458     mark_invoice (invoice);
   459     gncInvoiceCommitEdit (invoice);
   463 qofInvoiceSetOwner (GncInvoice *invoice, 
QofInstance *ent)
   465     if (!invoice || !ent)
   469     gncInvoiceBeginEdit (invoice);
   471     mark_invoice (invoice);
   472     gncInvoiceCommitEdit (invoice);
   476 qofInvoiceSetBillTo (GncInvoice *invoice, 
QofInstance *ent)
   478     if (!invoice || !ent)
   482     gncInvoiceBeginEdit (invoice);
   484     mark_invoice (invoice);
   485     gncInvoiceCommitEdit (invoice);
   494 void gncInvoiceSetDateOpened (GncInvoice *invoice, 
time64 date)
   496     if (!invoice) 
return;
   497     if (date == invoice->date_opened) 
return;
   498     gncInvoiceBeginEdit (invoice);
   499     invoice->date_opened = date;
   500     mark_invoice (invoice);
   501     gncInvoiceCommitEdit (invoice);
   504 void gncInvoiceSetDatePosted (GncInvoice *invoice, 
time64 date)
   506     if (!invoice) 
return;
   507     if (date == invoice->date_posted) 
return;
   508     gncInvoiceBeginEdit (invoice);
   509     invoice->date_posted = date;
   510     mark_invoice (invoice);
   511     gncInvoiceCommitEdit (invoice);
   514 void gncInvoiceSetTerms (GncInvoice *invoice, GncBillTerm *terms)
   516     if (!invoice) 
return;
   517     if (invoice->terms == terms) 
return;
   518     gncInvoiceBeginEdit (invoice);
   520         gncBillTermDecRef (invoice->terms);
   521     invoice->terms = terms;
   523         gncBillTermIncRef (invoice->terms);
   524     mark_invoice (invoice);
   525     gncInvoiceCommitEdit (invoice);
   528 void gncInvoiceSetBillingID (GncInvoice *invoice, 
const char *billing_id)
   530     if (!invoice) 
return;
   531     SET_STR (invoice, invoice->billing_id, billing_id);
   532     mark_invoice (invoice);
   533     gncInvoiceCommitEdit (invoice);
   536 void gncInvoiceSetNotes (GncInvoice *invoice, 
const char *notes)
   538     if (!invoice || !notes) 
return;
   539     SET_STR (invoice, invoice->notes, notes);
   540     mark_invoice (invoice);
   541     gncInvoiceCommitEdit (invoice);
   544 void gncInvoiceSetDocLink (GncInvoice *invoice, 
const char *doclink)
   546     if (!invoice || !doclink) 
return;
   548     gncInvoiceBeginEdit (invoice);
   550     if (doclink[0] == 
'\0')
   556         GValue v = G_VALUE_INIT;
   557         g_value_init (&v, G_TYPE_STRING);
   558         g_value_set_static_string (&v, doclink);
   562     qof_instance_set_dirty (QOF_INSTANCE(invoice));
   563     gncInvoiceCommitEdit (invoice);
   566 void gncInvoiceSetActive (GncInvoice *invoice, gboolean active)
   568     if (!invoice) 
return;
   569     if (invoice->active == active) 
return;
   570     gncInvoiceBeginEdit (invoice);
   571     invoice->active = active;
   572     mark_invoice (invoice);
   573     gncInvoiceCommitEdit (invoice);
   576 void gncInvoiceSetIsCreditNote (GncInvoice *invoice, gboolean credit_note)
   578      GValue v = G_VALUE_INIT;
   579     if (!invoice) 
return;
   580     gncInvoiceBeginEdit (invoice);
   581     g_value_init (&v, G_TYPE_INT64);
   582     g_value_set_int64 (&v, credit_note ? 1 : 0);
   585     mark_invoice (invoice);
   586     gncInvoiceCommitEdit (invoice);
   595 void gncInvoiceSetCurrency (GncInvoice *invoice, gnc_commodity *currency)
   597     if (!invoice || !currency) 
return;
   598     if (invoice->currency &&
   601     gncInvoiceBeginEdit (invoice);
   602     invoice->currency = currency;
   603     mark_invoice (invoice);
   604     gncInvoiceCommitEdit (invoice);
   607 void gncInvoiceSetBillTo (GncInvoice *invoice, 
GncOwner *billto)
   609     if (!invoice || !billto) 
return;
   612     gncInvoiceBeginEdit (invoice);
   613     gncOwnerCopy (billto, &invoice->billto);
   614     mark_invoice (invoice);
   615     gncInvoiceCommitEdit (invoice);
   618 void gncInvoiceSetToChargeAmount (GncInvoice *invoice, gnc_numeric amount)
   620     if (!invoice) 
return;
   622     gncInvoiceBeginEdit (invoice);
   623     invoice->to_charge_amount = amount;
   624     mark_invoice (invoice);
   625     gncInvoiceCommitEdit (invoice);
   628 void gncInvoiceSetPostedTxn (GncInvoice *invoice, Transaction *txn)
   630     if (!invoice) 
return;
   631     g_return_if_fail (invoice->posted_txn == NULL);
   633     gncInvoiceBeginEdit (invoice);
   634     invoice->posted_txn = txn;
   635     mark_invoice (invoice);
   636     gncInvoiceCommitEdit (invoice);
   639 void gncInvoiceSetPostedLot (GncInvoice *invoice, GNCLot *lot)
   641     if (!invoice) 
return;
   642     g_return_if_fail (invoice->posted_lot == NULL);
   644     gncInvoiceBeginEdit (invoice);
   645     invoice->posted_lot = lot;
   646     mark_invoice (invoice);
   647     gncInvoiceCommitEdit (invoice);
   650 void gncInvoiceSetPostedAcc (GncInvoice *invoice, 
Account *acc)
   652     if (!invoice) 
return;
   653     g_return_if_fail (invoice->posted_acc == NULL);
   655     gncInvoiceBeginEdit (invoice);
   656     invoice->posted_acc = acc;
   657     mark_invoice (invoice);
   658     gncInvoiceCommitEdit (invoice);
   661 void gncInvoiceAddEntry (GncInvoice *invoice, GncEntry *entry)
   667     if (!invoice || !entry) 
return;
   669     old = gncEntryGetInvoice (entry);
   670     if (old == invoice) 
return; 
   671     if (old) gncInvoiceRemoveEntry (old, entry);
   673     gncInvoiceBeginEdit (invoice);
   674     gncEntrySetInvoice (entry, invoice);
   675     invoice->entries = g_list_insert_sorted (invoice->entries, entry,
   676                        (GCompareFunc)gncEntryCompare);
   677     mark_invoice (invoice);
   678     gncInvoiceCommitEdit (invoice);
   681 void gncInvoiceRemoveEntry (GncInvoice *invoice, GncEntry *entry)
   683     if (!invoice || !entry) 
return;
   685     gncInvoiceBeginEdit (invoice);
   686     gncEntrySetInvoice (entry, NULL);
   687     invoice->entries = g_list_remove (invoice->entries, entry);
   688     mark_invoice (invoice);
   689     gncInvoiceCommitEdit (invoice);
   692 void gncInvoiceAddPrice (GncInvoice *invoice, GNCPrice *price)
   695     gnc_commodity *commodity;
   697     if (!invoice || !price) 
return;
   701     node = g_list_first (invoice->prices);
   702     commodity = gnc_price_get_commodity (price);
   705         GNCPrice *curr = (GNCPrice*)node->data;
   708         node = g_list_next (node);
   711     gncInvoiceBeginEdit (invoice);
   713         invoice->prices = g_list_delete_link (invoice->prices, node);
   714     invoice->prices = g_list_prepend (invoice->prices, price);
   715     mark_invoice (invoice);
   716     gncInvoiceCommitEdit (invoice);
   725     if (!bill || !entry) 
return;
   727     old = gncEntryGetBill (entry);
   728     if (old == bill) 
return;    
   729     if (old) gncBillRemoveEntry (old, entry);
   731     gncInvoiceBeginEdit (bill);
   732     gncEntrySetBill (entry, bill);
   733     bill->entries = g_list_insert_sorted (bill->entries, entry,
   734                                           (GCompareFunc)gncEntryCompare);
   736     gncInvoiceCommitEdit (bill);
   739 void gncBillRemoveEntry (GncInvoice *bill, GncEntry *entry)
   741     if (!bill || !entry) 
return;
   743     gncInvoiceBeginEdit (bill);
   744     gncEntrySetBill (entry, NULL);
   745     bill->entries = g_list_remove (bill->entries, entry);
   747     gncInvoiceCommitEdit (bill);
   752     if (!invoice) 
return;
   753     invoice->entries = g_list_sort (invoice->entries,
   754                                    (GCompareFunc)gncEntryCompare);
   755     gncInvoiceBeginEdit (invoice);
   756     mark_invoice (invoice);
   757     gncInvoiceCommitEdit (invoice);
   762     if (!invoice) 
return;
   766     for (GList *next, *node = invoice->entries; node; node = next)
   769         GncEntry *entry = node->data;
   771         switch (gncInvoiceGetOwnerType (invoice))
   773         case GNC_OWNER_VENDOR:
   774         case GNC_OWNER_EMPLOYEE:
   776             gncBillRemoveEntry (invoice, entry);
   778         case GNC_OWNER_CUSTOMER:
   781             gncInvoiceRemoveEntry (invoice, entry);
   788         if (!(gncEntryGetInvoice (entry) ||
   789               gncEntryGetBill (entry) ||
   790               gncEntryGetOrder (entry)))
   792             gncEntryBeginEdit (entry);
   793             gncEntryDestroy (entry);
   801 const char * gncInvoiceGetID (
const GncInvoice *invoice)
   803     if (!invoice) 
return NULL;
   807 const GncOwner * gncInvoiceGetOwner (
const GncInvoice *invoice)
   809     if (!invoice) 
return NULL;
   810     return &invoice->owner;
   813 static QofInstance * qofInvoiceGetOwner (GncInvoice *invoice)
   821     owner = &invoice->owner;
   822     return QOF_INSTANCE(owner);
   825 static QofInstance * qofInvoiceGetBillTo (GncInvoice *invoice)
   833     billto = &invoice->billto;
   834     return QOF_INSTANCE(billto);
   837 time64 gncInvoiceGetDateOpened (
const GncInvoice *invoice)
   839     if (!invoice) 
return INT64_MAX;
   840     return invoice->date_opened;
   843 time64 gncInvoiceGetDatePosted (
const GncInvoice *invoice)
   845     if (!invoice) 
return INT64_MAX;
   846     return invoice->date_posted;
   849 time64 gncInvoiceGetDateDue (
const GncInvoice *invoice)
   852     if (!invoice) 
return INT64_MAX;
   853     txn = gncInvoiceGetPostedTxn (invoice);
   854     if (!txn) 
return INT64_MAX;
   858 GncBillTerm * gncInvoiceGetTerms (
const GncInvoice *invoice)
   860     if (!invoice) 
return NULL;
   861     return invoice->terms;
   864 const char * gncInvoiceGetBillingID (
const GncInvoice *invoice)
   866     if (!invoice) 
return NULL;
   867     return invoice->billing_id;
   870 const char * gncInvoiceGetNotes (
const GncInvoice *invoice)
   872     if (!invoice) 
return NULL;
   873     return invoice->notes;
   876 const char * gncInvoiceGetDocLink (
const GncInvoice *invoice)
   878     if (!invoice) 
return NULL;
   880     GValue v = G_VALUE_INIT;
   882     const char *rv = G_VALUE_HOLDS_STRING(&v) ? g_value_get_string (&v) : NULL;
   888 GncOwnerType gncInvoiceGetOwnerType (
const GncInvoice *invoice)
   891     g_return_val_if_fail (invoice, GNC_OWNER_NONE);
   897 static gnc_numeric gncInvoiceSumTaxesInternal (AccountValueList *taxes)
   899     gnc_numeric tt = gnc_numeric_zero ();
   907         for (node = taxes; node; node=node->next)
   909             GncAccountValue *acc_val = node->data;
   917 static gnc_numeric gncInvoiceGetNetAndTaxesInternal (GncInvoice *invoice, gboolean use_value,
   918                                                      AccountValueList **taxes,
   919                                                      gboolean use_payment_type,
   920                                                      GncEntryPaymentType type)
   923     gnc_numeric net_total = gnc_numeric_zero ();
   924     gboolean is_cust_doc, is_cn;
   925     AccountValueList *tv_list = NULL;
   928     g_return_val_if_fail (invoice, net_total);
   934     is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
   935     is_cn = gncInvoiceGetIsCreditNote (invoice);
   938     for (node = gncInvoiceGetEntries (invoice); node; node = node->next)
   940         GncEntry *entry = node->data;
   943         if (use_payment_type && gncEntryGetBillPayment (entry) != type)
   950             value = gncEntryGetDocValue (entry, TRUE, is_cust_doc, is_cn);
   954                 PWARN (
"bad value in our entry");
   970         for (node = tv_list; node; node=node->next)
   972             GncAccountValue *acc_val = node->data;
   979     LEAVE (
"%" PRId64 
"/%" PRId64, net_total.num, net_total.denom);
   983 static gnc_numeric gncInvoiceGetTotalInternal (GncInvoice *invoice, gboolean use_value,
   985                                                gboolean use_payment_type, GncEntryPaymentType type)
   987     AccountValueList *taxes;
   990     if (!invoice) 
return gnc_numeric_zero ();
   993     total = gncInvoiceGetNetAndTaxesInternal (invoice, use_value, use_tax? &taxes : NULL, use_payment_type, type);
  1004     LEAVE (
"%" PRId64 
"/%" PRId64, total.num, total.denom);
  1010     if (!invoice) 
return gnc_numeric_zero ();
  1011     return gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, FALSE, 0);
  1014 gnc_numeric gncInvoiceGetTotalSubtotal (GncInvoice *invoice)
  1016     if (!invoice) 
return gnc_numeric_zero ();
  1017     return gncInvoiceGetTotalInternal (invoice, TRUE, FALSE, FALSE, 0);
  1020 gnc_numeric gncInvoiceGetTotalTax (GncInvoice *invoice)
  1022     if (!invoice) 
return gnc_numeric_zero ();
  1023     return gncInvoiceGetTotalInternal (invoice, FALSE, TRUE, FALSE, 0);
  1026 gnc_numeric gncInvoiceGetTotalOf (GncInvoice *invoice, GncEntryPaymentType type)
  1028     if (!invoice) 
return gnc_numeric_zero ();
  1029     return gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, TRUE, type);
  1034     AccountValueList *taxes;
  1035     if (!invoice) 
return NULL;
  1037     gncInvoiceGetNetAndTaxesInternal (invoice, FALSE, &taxes, FALSE, 0);
  1041 GList * gncInvoiceGetTypeListForOwnerType (GncOwnerType type)
  1043     GList *type_list = NULL;
  1046     case GNC_OWNER_CUSTOMER:
  1047         type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_CUST_INVOICE));
  1048         type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_CUST_CREDIT_NOTE));
  1050     case GNC_OWNER_VENDOR:
  1051         type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_VEND_INVOICE));
  1052         type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_VEND_CREDIT_NOTE));
  1054     case GNC_OWNER_EMPLOYEE:
  1055         type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_EMPL_INVOICE));
  1056         type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_EMPL_CREDIT_NOTE));
  1059         PWARN(
"Bad owner type, no invoices.");
  1065 GncInvoiceType gncInvoiceGetType (
const GncInvoice *invoice)
  1067     if (!invoice) 
return GNC_INVOICE_UNDEFINED;
  1068     switch (gncInvoiceGetOwnerType (invoice))
  1070     case GNC_OWNER_CUSTOMER:
  1071         return (gncInvoiceGetIsCreditNote (invoice) ?
  1072                 GNC_INVOICE_CUST_CREDIT_NOTE :
  1073                 GNC_INVOICE_CUST_INVOICE);
  1074     case GNC_OWNER_VENDOR:
  1075         return (gncInvoiceGetIsCreditNote (invoice) ?
  1076                 GNC_INVOICE_VEND_CREDIT_NOTE :
  1077                 GNC_INVOICE_VEND_INVOICE);
  1078     case GNC_OWNER_EMPLOYEE:
  1079         return (gncInvoiceGetIsCreditNote (invoice) ?
  1080                 GNC_INVOICE_EMPL_CREDIT_NOTE :
  1081                 GNC_INVOICE_EMPL_INVOICE);
  1083         PWARN (
"No invoice types defined for owner %d",
  1084                gncInvoiceGetOwnerType (invoice));
  1085         return GNC_INVOICE_UNDEFINED;
  1089 const char * gncInvoiceGetTypeString (
const GncInvoice *invoice)
  1091     GncInvoiceType type = gncInvoiceGetType (invoice);
  1094     case GNC_INVOICE_CUST_INVOICE:
  1095         return _(
"Invoice");
  1096     case GNC_INVOICE_VEND_INVOICE:
  1098     case GNC_INVOICE_EMPL_INVOICE:
  1099         return _(
"Expense");
  1100     case GNC_INVOICE_CUST_CREDIT_NOTE:
  1101     case GNC_INVOICE_VEND_CREDIT_NOTE:
  1102     case GNC_INVOICE_EMPL_CREDIT_NOTE:
  1103         return _(
"Credit Note");
  1105         PWARN(
"Unknown invoice type");
  1110 gnc_commodity * gncInvoiceGetCurrency (
const GncInvoice *invoice)
  1112     if (!invoice) 
return NULL;
  1113     return invoice->currency;
  1116 GncOwner * gncInvoiceGetBillTo (GncInvoice *invoice)
  1118     if (!invoice) 
return NULL;
  1119     return &invoice->billto;
  1122 GNCLot * gncInvoiceGetPostedLot (
const GncInvoice *invoice)
  1124     if (!invoice) 
return NULL;
  1125     return invoice->posted_lot;
  1128 Transaction * gncInvoiceGetPostedTxn (
const GncInvoice *invoice)
  1130     if (!invoice) 
return NULL;
  1131     return invoice->posted_txn;
  1134 Account * gncInvoiceGetPostedAcc (
const GncInvoice *invoice)
  1136     if (!invoice) 
return NULL;
  1137     return invoice->posted_acc;
  1140 gboolean gncInvoiceGetActive (
const GncInvoice *invoice)
  1142     if (!invoice) 
return FALSE;
  1143     return invoice->active;
  1146 gboolean gncInvoiceGetIsCreditNote (
const GncInvoice *invoice)
  1148     GValue v = G_VALUE_INIT;
  1150     if (!invoice) 
return FALSE;
  1152     retval = G_VALUE_HOLDS_INT64(&v) && g_value_get_int64 (&v);
  1158 gnc_numeric gncInvoiceGetToChargeAmount (
const GncInvoice *invoice)
  1160     if (!invoice) 
return gnc_numeric_zero ();
  1161     return invoice->to_charge_amount;
  1164 EntryList * gncInvoiceGetEntries (GncInvoice *invoice)
  1166     if (!invoice) 
return NULL;
  1167     return invoice->entries;
  1170 GNCPrice * gncInvoiceGetPrice (GncInvoice *invoice, gnc_commodity *commodity)
  1172     GList *node = g_list_first (invoice->prices);
  1174     while (node != NULL)
  1176         GNCPrice *curr = (GNCPrice*)node->data;
  1181         node = g_list_next (node);
  1187 static QofCollection*
  1188 qofInvoiceGetEntries (GncInvoice *invoice)
  1190     QofCollection *entry_coll;
  1195     for (list = gncInvoiceGetEntries (invoice); list != NULL; list = list->next)
  1197         entry = QOF_INSTANCE(list->data);
  1204 qofInvoiceEntryCB (
QofInstance *ent, gpointer user_data)
  1206     GncInvoice *invoice;
  1208     invoice = (GncInvoice*)user_data;
  1209     if (!invoice || !ent)
  1213     switch (gncInvoiceGetOwnerType (invoice))
  1215     case GNC_OWNER_VENDOR:
  1222         gncInvoiceAddEntry (invoice, (GncEntry*)ent);
  1229 qofInvoiceSetEntries (GncInvoice *invoice, QofCollection *entry_coll)
  1237         qof_collection_foreach (entry_coll, qofInvoiceEntryCB, invoice);
  1242 qofInvoiceGetJob (
const GncInvoice *invoice)
  1248     return invoice->job;
  1252 qofInvoiceSetJob (GncInvoice *invoice, GncJob *job)
  1262 gncInvoiceDetachFromLot (GNCLot *lot)
  1266     gnc_lot_begin_edit (lot);
  1268     gnc_lot_commit_edit (lot);
  1269     gnc_lot_set_cached_invoice (lot, NULL);
  1273 gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot)
  1276     if (!invoice || !lot)
  1279     if (invoice->posted_lot) 
return;    
  1281     gnc_lot_begin_edit (lot);
  1283     gnc_lot_commit_edit (lot);
  1284     gnc_lot_set_cached_invoice (lot, invoice);
  1285     gncInvoiceSetPostedLot (invoice, lot);
  1292     GncInvoice *invoice = NULL;
  1294     if (!lot) 
return NULL;
  1299         book = gnc_lot_get_book (lot);
  1301         invoice = gncInvoiceLookup (book, guid);
  1303         gnc_lot_set_cached_invoice (lot, invoice);
  1310 gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
  1312     if (!invoice || !txn)
  1315     if (invoice->posted_txn) 
return;    
  1322     gncInvoiceSetPostedTxn (invoice, txn);
  1330     GncInvoice *invoice = NULL;
  1332     if (!txn) 
return NULL;
  1336     invoice = gncInvoiceLookup (book, guid);
  1343     switch (gncInvoiceGetType (invoice))
  1345     case GNC_INVOICE_CUST_INVOICE:
  1346     case GNC_INVOICE_VEND_CREDIT_NOTE:
  1347     case GNC_INVOICE_EMPL_CREDIT_NOTE:
  1349     case GNC_INVOICE_CUST_CREDIT_NOTE:
  1350     case GNC_INVOICE_VEND_INVOICE:
  1351     case GNC_INVOICE_EMPL_INVOICE:
  1353     case GNC_INVOICE_UNDEFINED:
  1357         g_assert_not_reached ();
  1364     EntryList *entries_iter;
  1365     gboolean is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
  1366     gboolean is_cn = gncInvoiceGetIsCreditNote (invoice);
  1367     GHashTable *amt_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal,
  1371     for (entries_iter = invoice->entries; entries_iter != NULL; entries_iter = g_list_next(entries_iter))
  1373         GncEntry *entry = (GncEntry*)entries_iter->data;
  1375         gnc_commodity *account_currency;
  1376         AccountValueList *tt_amts = NULL, *tt_iter;
  1379         this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
  1380                     gncEntryGetBillAccount (entry));
  1386             gnc_numeric *curr_amt = (gnc_numeric*) g_hash_table_lookup (amt_hash, account_currency);
  1387             gnc_numeric *entry_amt = (gnc_numeric*) g_new0 (gnc_numeric, 1);
  1388             *entry_amt = gncEntryGetDocValue (entry, FALSE, is_cust_doc, is_cn);
  1391             g_hash_table_insert (amt_hash, account_currency, entry_amt);
  1401         for (tt_iter = tt_amts; tt_iter != NULL; tt_iter = g_list_next(tt_iter))
  1403             GncAccountValue *tt_amt_val = (GncAccountValue*)tt_iter->data;
  1404             Account *tt_acc = tt_amt_val->account;
  1410                 gnc_numeric *curr_amt = (gnc_numeric*) g_hash_table_lookup (amt_hash, tt_acc_currency);
  1411                 gnc_numeric *tt_acc_amt = (gnc_numeric*) g_new0 (gnc_numeric, 1);
  1412                 *tt_acc_amt = tt_amt_val->value;
  1415                 g_hash_table_insert (amt_hash, tt_acc_currency, tt_acc_amt);
  1425 static gboolean gncInvoicePostAddSplit (QofBook *book,
  1431                                         GncInvoice *invoice)
  1441     gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
  1478             PERR(
"Multiple commodities with no price.");
  1484             gnc_numeric converted_amount;
  1498                                        const char * memo, gboolean accumulatesplits,
  1505     GList *splitinfo = NULL;
  1507     gboolean is_cust_doc;
  1509     const char *name, *type;
  1514     AccountValueList *taxes;
  1516     if (!invoice || !acc) 
return NULL;
  1517     if (gncInvoiceIsPosted (invoice)) 
return NULL;
  1520     gncInvoiceBeginEdit (invoice);
  1525         gncInvoiceSetTerms (invoice,
  1526                             gncBillTermReturnChild (invoice->terms, TRUE));
  1529     is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
  1530     is_cn = gncInvoiceGetIsCreditNote (invoice);
  1534     if (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_EMPLOYEE)
  1538     lot = gnc_lot_new (book);
  1539     gncInvoiceAttachToLot (invoice, lot);
  1540     gnc_lot_begin_edit (lot);
  1542     type = gncInvoiceGetTypeString (invoice);
  1545     lot_title = g_strdup_printf (
"%s %s", type, gncInvoiceGetID (invoice));
  1546     gnc_lot_set_title (lot, lot_title);
  1558     gnc_set_num_action (txn, NULL, gncInvoiceGetID (invoice), type);
  1576     if (is_cust_doc != is_cn)
  1580         for (node = taxes; node; node = node->next)
  1582             GncAccountValue *acc_val = node->data;
  1591     for (iter = gncInvoiceGetEntries (invoice); iter; iter = iter->next)
  1593         gnc_numeric value, tax;
  1594         GncEntry * entry = iter->data;
  1598         gncEntryBeginEdit (entry);
  1600             gncEntrySetInvTaxTable
  1601             (entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE));
  1604             gncEntrySetBillTaxTable
  1605             (entry, gncTaxTableReturnChild (gncEntryGetBillTaxTable (entry), TRUE));
  1608             if (gncEntryGetBillable (entry))
  1611                 gncEntrySetInvPrice (entry, gncEntryGetPrice (entry, FALSE, TRUE));
  1612                 gncEntrySetInvTaxIncluded (entry, FALSE);
  1615         gncEntryCommitEdit (entry);
  1619         value = gncEntryGetBalValue (entry, TRUE, is_cust_doc);
  1620         tax   = gncEntryGetBalTaxValue (entry, TRUE, is_cust_doc);
  1622         DEBUG (
"Tax %" PRId64 
"/%" PRId64 
" on entry value %" PRId64 
"/%" PRId64,
  1623                tax.num, tax.denom, value.num, value.denom);
  1625         this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
  1626                     gncEntryGetBillAccount (entry));
  1631                 if (accumulatesplits)
  1634                 else if (!gncInvoicePostAddSplit (book, this_acc, txn, value,
  1635                                                   gncEntryGetDescription (entry),
  1642                     PERR(
"Failed to add split %s", gncEntryGetDescription (entry));
  1656                 if (ccard_acct && gncEntryGetBillPayment (entry) == GNC_PAYMENT_CARD)
  1666                     gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
  1678                 PWARN (
"bad value in our entry");
  1683             PWARN (
"bad tax in our entry");
  1694         PINFO (
"Processing Split List");
  1695     for (iter = splitinfo; iter; iter = iter->next)
  1697         GncAccountValue *acc_val = iter->data;
  1701         if (!gncInvoicePostAddSplit (book, acc_val->account, txn, acc_val->value,
  1702                                      memo, type, invoice))
  1708             PERR(
"Failed to add split %s, aborting accumulated splits.", memo);
  1722         gnc_numeric to_charge_bal_amount = (is_cn ? 
gnc_numeric_neg (invoice->to_charge_amount)
  1723                                             : invoice->to_charge_amount);
  1725         PINFO (
"Process to_card payment split");
  1729         gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
  1746         PINFO (
"Process to_card balancing split");
  1750         gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
  1764     gncInvoiceAttachToTxn (invoice, txn);
  1765     gncInvoiceSetPostedAcc (invoice, acc);
  1772     gnc_lot_commit_edit (lot);
  1775     DEBUG(
"Committing Invoice %s", invoice->id);
  1776     mark_invoice (invoice);
  1777     gncInvoiceCommitEdit (invoice);
  1794     GList *lot_split_list, *lot_split_iter;
  1796     if (!invoice) 
return FALSE;
  1797     if (!gncInvoiceIsPosted (invoice)) 
return FALSE;
  1799     txn = gncInvoiceGetPostedTxn (invoice);
  1800     g_return_val_if_fail (txn, FALSE);
  1802     lot = gncInvoiceGetPostedLot (invoice);
  1803     g_return_val_if_fail (lot, FALSE);
  1807     xaccTransClearReadOnly (txn);
  1813     gncInvoiceDetachFromLot (lot);
  1832         PINFO (
"Recreating link transactions for remaining lots");
  1833     for (lot_split_iter = lot_split_list; lot_split_iter; lot_split_iter = lot_split_iter->next)
  1835         Split *split = lot_split_iter->data;
  1836         GList *other_split_list, *list_iter;
  1838         GList *lot_list = NULL;
  1847         for (list_iter = other_split_list; list_iter; list_iter = list_iter->next)
  1849             Split *other_split = list_iter->data;
  1853             if (other_lot == lot)
  1856             lot_list = g_list_prepend (lot_list, other_lot);
  1859         lot_list = g_list_reverse (lot_list);
  1862         xaccTransClearReadOnly (other_txn);
  1873         for (list_iter = lot_list; list_iter; list_iter = list_iter->next)
  1875             GNCLot *other_lot = list_iter->data;
  1878             if (!gnc_lot_count_splits (other_lot))
  1879                 gnc_lot_destroy (other_lot);
  1880             else if (other_invoice)
  1881                 qof_event_gen (QOF_INSTANCE(other_invoice), QOF_EVENT_MODIFY, NULL);
  1883         g_list_free (lot_list);
  1885     g_list_free (lot_split_list);
  1888     if (!gnc_lot_count_splits (lot))
  1889         gnc_lot_destroy (lot);
  1892     gncInvoiceBeginEdit (invoice);
  1894     invoice->posted_acc = NULL;
  1895     invoice->posted_txn = NULL;
  1896     invoice->posted_lot = NULL;
  1897     invoice->date_posted = INT64_MAX;
  1900     if (reset_tax_tables)
  1902         gboolean is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
  1905         for (iter = gncInvoiceGetEntries (invoice); iter; iter = iter->next)
  1907             GncEntry *entry = iter->data;
  1909             gncEntryBeginEdit (entry);
  1911                 gncEntrySetInvTaxTable (entry,
  1912                                         gncTaxTableGetParent (gncEntryGetInvTaxTable( entry)));
  1914                 gncEntrySetBillTaxTable (entry,
  1915                                          gncTaxTableGetParent (gncEntryGetBillTaxTable (entry)));
  1916             gncEntryCommitEdit (entry);
  1920     mark_invoice (invoice);
  1921     gncInvoiceCommitEdit (invoice);
  1931     gboolean positive_balance;
  1935 gnc_lot_match_owner_balancing (GNCLot *lot, gpointer user_data)
  1977     g_return_if_fail (invoice);
  1978     g_return_if_fail (invoice->posted_lot);
  1980     inv_lot = invoice->posted_lot;
  1981     acct = invoice->posted_acc;
  1995     lot_list = g_list_prepend (lot_list, inv_lot);
  1997     g_list_free (lot_list);
  2006                         Account *xfer_acc, gnc_numeric amount,
  2007                         gnc_numeric exch, 
time64 date,
  2008                         const char *memo, 
const char *num)
  2010     GNCLot *payment_lot;
  2011     GList *selected_lots = NULL;
  2015     if (!invoice || !gncInvoiceIsPosted (invoice) || !xfer_acc) 
return;
  2018     g_return_if_fail (owner->owner.undefined);
  2022                                                 invoice->posted_acc,
  2023                                                 xfer_acc, amount, exch,
  2027     selected_lots = g_list_prepend (selected_lots, invoice->posted_lot);
  2031         selected_lots = g_list_prepend (selected_lots, payment_lot);
  2035 gboolean gncInvoiceIsPosted (
const GncInvoice *invoice)
  2037     if (!invoice) 
return FALSE;
  2038     return GNC_IS_TRANSACTION(gncInvoiceGetPostedTxn (invoice));
  2041 gboolean gncInvoiceIsPaid (
const GncInvoice *invoice)
  2043     if (!invoice) 
return FALSE;
  2044     if (!invoice->posted_lot) 
return FALSE;
  2050 void gncInvoiceBeginEdit (GncInvoice *invoice)
  2057     PERR(
"Invoice QofBackend Failure: %d", errcode);
  2058     gnc_engine_signal_commit_error (errcode);
  2061 static void gncInvoiceOnDone (
QofInstance *invoice) { }
  2065     GncInvoice *invoice = (GncInvoice *) inst;
  2066     gncInvoiceFree (invoice);
  2069 void gncInvoiceCommitEdit (GncInvoice *invoice)
  2073                            gncInvoiceOnDone, invoice_free);
  2076 int gncInvoiceCompare (
const GncInvoice *a, 
const GncInvoice *b)
  2080     if (a == b) 
return 0;
  2084     compare = g_strcmp0 (a->id, b->id);
  2085     if (compare) 
return compare;
  2086     if (a->date_opened != b->date_opened) 
return a->date_opened - b->date_opened;
  2087     if (a->date_posted != b->date_posted) 
return a->date_posted - b->date_posted;
  2093     if (a == NULL && b == NULL) 
return TRUE;
  2094     if (a == NULL || b == NULL) 
return FALSE;
  2096     g_return_val_if_fail (GNC_IS_INVOICE(a), FALSE);
  2097     g_return_val_if_fail (GNC_IS_INVOICE(b), FALSE);
  2099     if (g_strcmp0 (a->id, b->id) != 0)
  2101         PWARN(
"IDs differ: %s vs %s", a->id, b->id);
  2105     if (g_strcmp0 (a->notes, b->notes) != 0)
  2107         PWARN(
"Notes differ: %s vs %s", a->notes, b->notes);
  2111     if (g_strcmp0 (a->billing_id, b->billing_id) != 0)
  2113         PWARN(
"Billing IDs differ: %s vs %s", a->billing_id, b->billing_id);
  2117     if (g_strcmp0 (a->printname, b->printname) != 0)
  2119         PWARN(
"Printnames differ: %s vs %s", a->printname, b->printname);
  2123     if (a->active != b->active)
  2125         PWARN(
"Active flags differ");
  2131         PWARN(
"Billterms differ");
  2135     if (!gncJobEqual (a->job, b->job))
  2137         PWARN(
"Jobs differ");
  2143         PWARN(
"Currencies differ");
  2149         PWARN(
"Posted accounts differ");
  2153     if (!
xaccTransEqual (a->posted_txn, b->posted_txn, TRUE, TRUE, TRUE, FALSE))
  2155         PWARN(
"Posted tx differ");
  2160     if (!gncLotEqual (a->posted_lot, b->posted_lot))
  2162         PWARN(
"Posted lots differ");
  2176     gnc_numeric to_charge_amount;
  2185 static const char * _gncInvoicePrintable (gpointer obj)
  2187     GncInvoice *invoice = obj;
  2189     g_return_val_if_fail (invoice, NULL);
  2193         if (invoice->printname) g_free (invoice->printname);
  2195         invoice->printname =
  2196             g_strdup_printf (
"%s%s", invoice->id,
  2197                              gncInvoiceIsPosted (invoice) ? _(
" (posted)") : 
"");
  2200     return invoice->printname;
  2204 destroy_invoice_on_book_close (
QofInstance *ent, gpointer data)
  2206     GncInvoice* invoice = GNC_INVOICE(ent);
  2208     gncInvoiceBeginEdit (invoice);
  2209     gncInvoiceDestroy (invoice);
  2213 gnc_invoice_book_end (QofBook* book)
  2218     qof_collection_foreach (col, destroy_invoice_on_book_close, NULL);
  2221 static QofObject gncInvoiceDesc =
  2224     DI(.e_type            = ) _GNC_MOD_NAME,
  2225     DI(.type_label        = ) "Invoice",
  2226     DI(.create            = ) (gpointer)gncInvoiceCreate,
  2227     DI(.book_begin        = ) NULL,
  2228     DI(.book_end          = ) gnc_invoice_book_end,
  2231     DI(.foreach           = ) qof_collection_foreach,
  2232     DI(.printable         = ) _gncInvoicePrintable,
  2239     static QofParam params[] =
  2242             INVOICE_FROM_LOT, _GNC_MOD_NAME,
  2254     static QofParam params[] =
  2257             INVOICE_FROM_TXN, _GNC_MOD_NAME,
  2266 gboolean gncInvoiceRegister (
void)
  2268     static QofParam params[] =
  2271         { INVOICE_OWNER,     GNC_ID_OWNER,     (
QofAccessFunc)gncInvoiceGetOwner, NULL },
  2273         { INVOICE_DUE,       QOF_TYPE_DATE,    (
QofAccessFunc)gncInvoiceGetDateDue, NULL },
  2275         { INVOICE_IS_POSTED, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncInvoiceIsPosted, NULL },
  2276         { INVOICE_IS_PAID,   QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncInvoiceIsPaid,    NULL },
  2282         { INVOICE_POST_LOT,  GNC_ID_LOT,       (
QofAccessFunc)gncInvoiceGetPostedLot, NULL },
  2283         { INVOICE_TYPE,      QOF_TYPE_INT32,   (
QofAccessFunc)gncInvoiceGetType,    NULL },
  2284         { INVOICE_TYPE_STRING, QOF_TYPE_STRING, (
QofAccessFunc)gncInvoiceGetTypeString,    NULL },
  2286         { INVOICE_BILLTO,    GNC_ID_OWNER,     (
QofAccessFunc)gncInvoiceGetBillTo, NULL  },
  2303         qofInvoiceSetEntries (NULL, NULL);
  2304         qofInvoiceGetEntries (NULL);
  2305         qofInvoiceSetOwner (NULL, NULL);
  2306         qofInvoiceGetOwner (NULL);
  2307         qofInvoiceSetBillTo (NULL, NULL);
  2308         qofInvoiceGetBillTo (NULL);
  2313 gchar *gncInvoiceNextID (QofBook *book, 
const GncOwner *owner)
  2318     case GNC_OWNER_CUSTOMER:
  2321     case GNC_OWNER_VENDOR:
  2324     case GNC_OWNER_EMPLOYEE:
 void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity. 
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. 
Transaction * xaccMallocTransaction(QofBook *book)
 The xaccMallocTransaction() will malloc memory and initialize it. 
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number. 
void xaccSplitSetBaseValue(Split *s, gnc_numeric value, const gnc_commodity *base_currency)
Depending on the base_currency, set either the value or the amount of this split or both: If the base...
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity. 
#define QOF_TYPE_COLLECT
secondary collections are used for one-to-many references between entities and are implemented using ...
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance. 
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. 
char xaccTransGetTxnType(Transaction *trans)
Returns the Transaction Type: note this type will be derived from the transaction splits...
#define TXN_TYPE_INVOICE
Transaction is an invoice. 
#define PINFO(format, args...)
Print an informational note. 
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. 
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account. 
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
gchar * qof_book_increment_and_format_counter(QofBook *book, const char *counter_name)
This will increment the named counter for this book and format it. 
GList * qof_instance_get_referring_object_list_from_collection(const QofCollection *coll, const QofInstance *ref)
Returns a list of objects from the collection which refer to the specific object. ...
#define DEBUG(format, args...)
Print a debugging message. 
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 gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature. 
AccountValueList * gncEntryGetDocTaxValues(GncEntry *entry, gboolean is_cust_doc, gboolean is_cn)
Careful: the returned list is NOT owned by the entry and should be freed by the caller. 
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. 
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal. 
void gnc_lot_add_split(GNCLot *lot, Split *split)
Adds a split to this lot. 
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description. 
gboolean gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking. 
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b. 
void gncInvoiceRemoveEntries(GncInvoice *invoice)
Remove all entries from an invoice. 
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0. 
Transaction * gncInvoicePostToAccount(GncInvoice *invoice, Account *acc, time64 post_date, time64 due_date, const char *memo, gboolean accumulatesplits, gboolean autopay)
Post this invoice to an account. 
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split. 
QofCollection * qof_instance_get_collection(gconstpointer ptr)
Return the collection this instance belongs to. 
Use any denominator which gives an exactly correct ratio of numerator to denominator. 
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type. 
GHashTable * gncInvoiceGetForeignCurrencies(const GncInvoice *invoice)
Return an overview of amounts on this invoice that will be posted to accounts in currencies that are ...
void gncInvoiceSortEntries(GncInvoice *invoice)
Call this function when an Entry is changed and you want to re-sort the list of entries. 
#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 
gnc_numeric gncInvoiceGetTotal(GncInvoice *invoice)
Return the "total" amount of the invoice as seen on the document (and shown to the user in the report...
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. 
gboolean gncBillTermEqual(const GncBillTerm *a, const GncBillTerm *b)
Check if all internal fields of a and b match. 
QofInstance * qofOwnerGetOwner(const GncOwner *owner)
return the owner itself as an entity. 
void gncInvoiceAutoApplyPayments(GncInvoice *invoice)
Attempt to pay the invoice using open payment lots and lots for documents of the opposite sign (credi...
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction. 
void gncOwnerAutoApplyPaymentsWithLots(const GncOwner *owner, GList *lots)
Given a list of lots, try to balance as many of them as possible by creating balancing transactions b...
GncInvoice * gncInvoiceGetInvoiceFromTxn(const Transaction *txn)
Given a transaction, find and return the Invoice. 
void xaccTransDestroy(Transaction *trans)
Destroys a transaction. 
#define PWARN(format, args...)
Log a warning. 
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 xaccTransSetTxnType(Transaction *trans, char type)
Set the Transaction Type: note the type will be saved into the Transaction kvp property as a backward...
gdouble gnc_numeric_to_double(gnc_numeric n)
Convert numeric to floating-point value. 
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
gboolean xaccTransEqual(const Transaction *ta, const Transaction *tb, gboolean check_guids, gboolean check_splits, gboolean check_balances, gboolean assume_ordered)
Equality. 
Account handling public routines. 
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Change the denominator of a gnc_numeric value to the specified denominator under standard arguments '...
Find the least common multiple of the arguments' denominators and use that as the denominator of the ...
void xaccTransSetReadOnly(Transaction *trans, const char *reason)
Set the transaction to be ReadOnly by setting a non-NULL value as "reason". 
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split. 
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object has been modified. 
SplitList * gnc_lot_get_split_list(const GNCLot *lot)
Returns a list of all the splits in this lot. 
void gncBillAddEntry(GncInvoice *bill, GncEntry *entry)
Call this function when adding an entry to a bill instead of an invoice. 
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction. 
void qofOwnerSetEntity(GncOwner *owner, QofInstance *ent)
set the owner from the entity. 
void gncInvoiceApplyPayment(const GncInvoice *invoice, Transaction *txn, Account *xfer_acc, gnc_numeric amount, gnc_numeric exch, time64 date, const char *memo, const char *num)
A convenience function to apply a payment to an invoice. 
void gncOwnerAttachToLot(const GncOwner *owner, GNCLot *lot)
Attach an owner to a lot. 
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day. 
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 
gboolean gncOwnerGetOwnerFromLot(GNCLot *lot, GncOwner *owner)
Get the owner from the lot. 
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions. 
#define xaccTransGetBook(X)
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag 
void xaccTransSetDateDue(Transaction *trans, time64 time)
Dates and txn-type for A/R and A/P "invoice" postings. 
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
Division. 
void gncAccountValueDestroy(GList *list)
Destroy a list of accountvalues. 
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare. 
#define TXN_TYPE_LINK
Transaction is a link between (invoice and payment) lots. 
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
GNCLot * gncOwnerCreatePaymentLotSecs(const GncOwner *owner, Transaction **preset_txn, Account *posted_acc, Account *xfer_acc, gnc_numeric amount, gnc_numeric exch, time64 date, const char *memo, const char *num)
Create a lot for a payment to the owner using the other parameters passed in. 
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0. 
Split * xaccMallocSplit(QofBook *book)
Constructor. 
void gncInvoiceSetDateOpenedGDate(GncInvoice *invoice, const GDate *date)
Set the DateOpened using a GDate argument. 
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b. 
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner. 
const GncOwner * gncOwnerGetEndOwner(const GncOwner *owner)
Get the "parent" Owner or GncGUID thereof. 
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot. 
Business Invoice Interface. 
QofIdType qof_collection_get_type(const QofCollection *col)
return the type that the collection stores 
gboolean gncInvoiceUnpost(GncInvoice *invoice, gboolean reset_tax_tables)
Unpost this invoice. 
gboolean qof_collection_add_entity(QofCollection *coll, QofInstance *ent)
Add an entity to a QOF_TYPE_COLLECT. 
gboolean gnc_lot_is_closed(GNCLot *lot)
Returns closed status of the given lot. 
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity. 
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances. 
GList * gncAccountValueAddList(GList *l1, GList *l2)
Merge l2 into l1. 
#define LEAVE(format, args...)
Print a function exit debugging message. 
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
time64 gnc_time(time64 *tbuf)
get the current time 
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. 
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
gboolean qof_object_register(const QofObject *object)
Register new types of object objects. 
GList * gncAccountValueAdd(GList *list, Account *acc, gnc_numeric value)
This will add value to the account-value for acc, creating a new list object if necessary. 
LotList * xaccAccountFindOpenLots(const Account *acc, gboolean(*match_func)(GNCLot *lot, gpointer user_data), gpointer user_data, GCompareFunc sort_func)
Find a list of open lots that match the match_func. 
Business Entry Interface. 
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered. 
gboolean gncInvoiceEqual(const GncInvoice *a, const GncInvoice *b)
Test support function used by test-dbi-business-stuff.c. 
time64 time64CanonicalDayTime(time64 t)
convert a time64 on a certain day (localtime) to the time64 representing midday on that day...
gboolean qof_book_shutting_down(const QofBook *book)
Is the book shutting down? 
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments. 
GncEmployee * gncOwnerGetEmployee(const GncOwner *owner)
If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object...
AccountValueList * gncInvoiceGetTotalTaxList(GncInvoice *invoice)
Return a list of tax totals accumulated per tax account. 
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument. 
API for Transactions and Splits (journal entries) 
The type used to store guids in C. 
GncInvoice * gncInvoiceCopy(const GncInvoice *from)
Create a new GncInvoice object as a deep copy of the given other invoice. 
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
time64 xaccTransRetDateDue(const Transaction *trans)
Dates and txn-type for A/R and A/P "invoice" postings. 
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction. 
gboolean gncInvoiceAmountPositive(const GncInvoice *invoice)
Depending on the invoice type, invoices have a different effect on the balance. 
gnc_numeric gnc_lot_get_balance(GNCLot *lot)
Returns the lot balance. 
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn't be...
QofCollection * qof_collection_new(QofIdType type)
create a new collection of entities of type 
gchar * qof_instance_get_display_name(const QofInstance *inst)
Returns a displayable name for this object. 
Utility functions for file access.