31 #include <qofinstance-p.h>    37 #include "gncEntryP.h"    57     gboolean    i_taxincluded;
    59     gnc_numeric     i_discount;
    61     GncDiscountHow i_disc_how;
    67     gboolean    b_taxincluded;
    73     GncEntryPaymentType b_payment;
    81     gboolean    values_dirty;
    85     gnc_numeric i_value_rounded;
    87     gnc_numeric i_tax_value;
    88     gnc_numeric i_tax_value_rounded;
    89     gnc_numeric i_disc_value;
    90     gnc_numeric i_disc_value_rounded;
    95     gnc_numeric b_value_rounded;
    97     gnc_numeric b_tax_value;
    98     gnc_numeric b_tax_value_rounded;
   104     QofInstanceClass parent_class;
   107 static QofLogModule log_module = GNC_MOD_BUSINESS;
   117     case (GNC_DISC_PRETAX):
   119     case (GNC_DISC_SAMETIME):
   121     case (GNC_DISC_POSTTAX):
   124         PWARN (
"asked to translate unknown discount-how %d.\n", how);
   132 gboolean gncEntryDiscountStringToHow (
const char *str, GncDiscountHow *how)
   134     if (g_strcmp0 (
"PRETAX", str) == 0)
   136         *how = GNC_DISC_PRETAX;
   139     if (g_strcmp0 (
"SAMETIME", str) == 0)
   141         *how = GNC_DISC_SAMETIME;
   144     if (g_strcmp0 (
"POSTTAX", str) == 0)
   146         *how = GNC_DISC_POSTTAX;
   149     PWARN (
"asked to translate unknown discount-how string %s.\n",
   150                str ? str : 
"(null)");
   157 const char * gncEntryPaymentTypeToString (GncEntryPaymentType type)
   161     case (GNC_PAYMENT_CASH):
   163     case (GNC_PAYMENT_CARD):
   166         PWARN (
"asked to translate unknown payment type %d.\n", type);
   174 gboolean gncEntryPaymentStringToType (
const char *str, GncEntryPaymentType *type)
   176     if (g_strcmp0 (
"CASH", str) == 0)
   178         *type = GNC_PAYMENT_CASH;
   181     if (g_strcmp0 (
"CARD", str) == 0)
   183         *type = GNC_PAYMENT_CARD;
   186     PWARN (
"asked to translate unknown discount-how string %s.\n",
   187                str ? str : 
"(null)");
   192 #define _GNC_MOD_NAME GNC_ID_ENTRY   194 #define SET_STR(obj, member, str) { \   195     if (!g_strcmp0 (member, str)) return; \   196     gncEntryBeginEdit (obj); \   197     CACHE_REPLACE (member, str); \   200 static inline void mark_entry (GncEntry *entry);
   201 void mark_entry (GncEntry *entry)
   203     qof_instance_set_dirty(&entry->inst);
   241 G_DEFINE_TYPE(GncEntry, gnc_entry, QOF_TYPE_INSTANCE)
   244 gnc_entry_init(GncEntry* entry)
   249 gnc_entry_dispose(GObject *entryp)
   251     G_OBJECT_CLASS(gnc_entry_parent_class)->dispose(entryp);
   255 gnc_entry_finalize(GObject* entryp)
   257     G_OBJECT_CLASS(gnc_entry_parent_class)->finalize(entryp);
   261 gnc_entry_get_property (GObject         *
object,
   268     g_return_if_fail(GNC_IS_ENTRY(
object));
   270     entry = GNC_ENTRY(
object);
   273     case PROP_DESCRIPTION:
   274         g_value_set_string(value, entry->desc);
   277         G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
   283 gnc_entry_set_property (GObject         *
object,
   290     g_return_if_fail(GNC_IS_ENTRY(
object));
   292     entry = GNC_ENTRY(
object);
   293     g_assert (qof_instance_get_editlevel(entry));
   297     case PROP_DESCRIPTION:
   298         gncEntrySetDescription(entry, g_value_get_string(value));
   301         G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
   314     g_return_val_if_fail(inst != NULL, FALSE);
   315     g_return_val_if_fail(GNC_IS_ENTRY(inst), FALSE);
   317     entry = GNC_ENTRY(inst);
   318     if (entry->order != NULL)
   321         s = g_strdup_printf(
"Entry in %s", display_name);
   322         g_free(display_name);
   325     if (entry->invoice != NULL)
   328         s = g_strdup_printf(
"Entry in %s", display_name);
   329         g_free(display_name);
   332     if (entry->bill != NULL)
   335         s = g_strdup_printf(
"Entry in %s", display_name);
   336         g_free(display_name);
   340     return g_strdup_printf(
"Entry %p", inst);
   349     g_return_val_if_fail(inst != NULL, FALSE);
   350     g_return_val_if_fail(GNC_IS_ENTRY(inst), FALSE);
   352     entry = GNC_ENTRY(inst);
   354     if (GNC_IS_ACCOUNT(ref))
   356         Account* acc = GNC_ACCOUNT(ref);
   357         return (entry->i_account == acc || entry->b_account == acc);
   359     else if (GNC_IS_TAXTABLE(ref))
   362         return (entry->i_tax_table == tt || entry->b_tax_table == tt);
   377     if (!GNC_IS_ACCOUNT(ref) && !GNC_IS_TAXTABLE(ref))
   386 gnc_entry_class_init (GncEntryClass *klass)
   388     GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   389     QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
   391     gobject_class->dispose = gnc_entry_dispose;
   392     gobject_class->finalize = gnc_entry_finalize;
   393     gobject_class->set_property = gnc_entry_set_property;
   394     gobject_class->get_property = gnc_entry_get_property;
   396     qof_class->get_display_name = impl_get_display_name;
   397     qof_class->refers_to_object = impl_refers_to_object;
   398     qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
   400     g_object_class_install_property
   403      g_param_spec_string (
"description",
   405                           "The description is an arbitrary string "   406                           "assigned by the user.  It provides identification "   413 GncEntry *gncEntryCreate (QofBook *book)
   416     gnc_numeric zero = gnc_numeric_zero ();
   418     if (!book) 
return NULL;
   420     entry = g_object_new (GNC_TYPE_ENTRY, NULL);
   423     entry->desc = CACHE_INSERT (
"");
   424     entry->action = CACHE_INSERT (
"");
   425     entry->notes = CACHE_INSERT (
"");
   426     entry->quantity = zero;
   428     entry->i_price = zero;
   429     entry->i_taxable = TRUE;
   430     entry->i_discount = zero;
   432     entry->i_disc_how = GNC_DISC_PRETAX;
   434     entry->b_price = zero;
   435     entry->b_taxable = TRUE;
   436     entry->billto.type = GNC_OWNER_CUSTOMER;
   437     entry->b_payment = GNC_PAYMENT_CASH;
   439     entry->values_dirty = TRUE;
   446 void gncEntryDestroy (GncEntry *entry)
   449     qof_instance_set_destroying(entry, TRUE);
   450     gncEntryCommitEdit(entry);
   453 static void gncEntryFree (GncEntry *entry)
   459     CACHE_REMOVE (entry->desc);
   460     CACHE_REMOVE (entry->action);
   461     CACHE_REMOVE (entry->notes);
   462     if (entry->i_tax_values)
   464     if (entry->b_tax_values)
   469         if (entry->i_tax_table)
   470             gncTaxTableDecRef (entry->i_tax_table);
   471         if (entry->b_tax_table)
   472             gncTaxTableDecRef (entry->b_tax_table);
   476     g_object_unref (entry);
   484     gboolean first_date = FALSE;
   486     if (entry->date == date) 
return;
   489     gncEntryBeginEdit (entry);
   492     gncEntryCommitEdit (entry);
   506     if (!entry || !date || !g_date_valid(date))
   517 void gncEntrySetDateEntered (GncEntry *entry, 
time64 date)
   520     if (entry->date_entered == date) 
return;
   521     gncEntryBeginEdit (entry);
   522     entry->date_entered = date;
   524     gncEntryCommitEdit (entry);
   527 void gncEntrySetDescription (GncEntry *entry, 
const char *desc)
   529     if (!entry || !desc) 
return;
   530     SET_STR (entry, entry->desc, desc);
   532     gncEntryCommitEdit (entry);
   535 void gncEntrySetAction (GncEntry *entry, 
const char *action)
   537     if (!entry || !action) 
return;
   538     SET_STR (entry, entry->action, action);
   540     gncEntryCommitEdit (entry);
   543 void gncEntrySetNotes (GncEntry *entry, 
const char *notes)
   545     if (!entry || !notes) 
return;
   546     SET_STR (entry, entry->notes, notes);
   548     gncEntryCommitEdit (entry);
   555     gncEntryBeginEdit (entry);
   556     entry->quantity = quantity;
   557     entry->values_dirty = TRUE;
   559     gncEntryCommitEdit (entry);
   566     gncEntryBeginEdit (entry);
   568     entry->values_dirty = TRUE;
   570     gncEntryCommitEdit (entry);
   575 void gncEntrySetInvAccount (GncEntry *entry, 
Account *acc)
   578     if (entry->i_account == acc) 
return;
   579     gncEntryBeginEdit (entry);
   580     entry->i_account = acc;
   582     gncEntryCommitEdit (entry);
   585 void gncEntrySetInvPrice (GncEntry *entry, gnc_numeric price)
   589     gncEntryBeginEdit (entry);
   590     entry->i_price = price;
   591     entry->values_dirty = TRUE;
   593     gncEntryCommitEdit (entry);
   596 void gncEntrySetInvTaxable (GncEntry *entry, gboolean taxable)
   600     ENTER (
"%d", taxable);
   601     if (entry->i_taxable == taxable) {
   602          LEAVE (
"Value already set");
   605     gncEntryBeginEdit (entry);
   606     entry->i_taxable = taxable;
   607     entry->values_dirty = TRUE;
   609     gncEntryCommitEdit (entry);
   613 void gncEntrySetInvTaxIncluded (GncEntry *entry, gboolean taxincluded)
   617     ENTER (
"%d", taxincluded);
   618     if (entry->i_taxincluded == taxincluded) {
   619          LEAVE (
"Value already set");
   622     gncEntryBeginEdit (entry);
   623     entry->i_taxincluded = taxincluded;
   624     entry->values_dirty = TRUE;
   626     gncEntryCommitEdit (entry);
   635     if (entry->i_tax_table == 
table) {
   636          LEAVE (
"Value already set");
   639     gncEntryBeginEdit (entry);
   640     if (entry->i_tax_table)
   641         gncTaxTableDecRef (entry->i_tax_table);
   643         gncTaxTableIncRef (
table);
   644     entry->i_tax_table = 
table;
   645     entry->values_dirty = TRUE;
   647     gncEntryCommitEdit (entry);
   651 void gncEntrySetInvDiscount (GncEntry *entry, gnc_numeric discount)
   655     gncEntryBeginEdit (entry);
   656     entry->i_discount = discount;
   657     entry->values_dirty = TRUE;
   659     gncEntryCommitEdit (entry);
   662 void gncEntrySetInvDiscountType (GncEntry *entry, 
GncAmountType type)
   665     if (entry->i_disc_type == type) 
return;
   667     gncEntryBeginEdit (entry);
   668     entry->i_disc_type = type;
   669     entry->values_dirty = TRUE;
   671     gncEntryCommitEdit (entry);
   674 void gncEntrySetInvDiscountHow (GncEntry *entry, GncDiscountHow how)
   677     if (entry->i_disc_how == how) 
return;
   679     gncEntryBeginEdit (entry);
   680     entry->i_disc_how = how;
   681     entry->values_dirty = TRUE;
   683     gncEntryCommitEdit (entry);
   686 void qofEntrySetInvDiscType (GncEntry *entry, 
const char *type_string)
   691     gncAmountStringToType(type_string, &type);
   692     if (entry->i_disc_type == type) 
return;
   693     gncEntryBeginEdit (entry);
   694     entry->i_disc_type = type;
   695     entry->values_dirty = TRUE;
   697     gncEntryCommitEdit (entry);
   701 void qofEntrySetInvDiscHow  (GncEntry *entry, 
const char *type)
   703     GncDiscountHow how = GNC_DISC_PRETAX;
   706     gncEntryBeginEdit (entry);
   707     gncEntryDiscountStringToHow(type, &how);
   708     if (entry->i_disc_how == how) 
return;
   709     entry->i_disc_how = how;
   710     entry->values_dirty = TRUE;
   712     gncEntryCommitEdit (entry);
   717 void gncEntrySetBillAccount (GncEntry *entry, 
Account *acc)
   720     if (entry->b_account == acc) 
return;
   721     gncEntryBeginEdit (entry);
   722     entry->b_account = acc;
   724     gncEntryCommitEdit (entry);
   727 void gncEntrySetBillPrice (GncEntry *entry, gnc_numeric price)
   731     gncEntryBeginEdit (entry);
   732     entry->b_price = price;
   733     entry->values_dirty = TRUE;
   735     gncEntryCommitEdit (entry);
   738 void gncEntrySetBillTaxable (GncEntry *entry, gboolean taxable)
   742     ENTER (
"%d", taxable);
   743     if (entry->b_taxable == taxable) {
   744          LEAVE (
"Value already set");
   747     gncEntryBeginEdit (entry);
   748     entry->b_taxable = taxable;
   749     entry->values_dirty = TRUE;
   751     gncEntryCommitEdit (entry);
   755 void gncEntrySetBillTaxIncluded (GncEntry *entry, gboolean taxincluded)
   759     ENTER (
"%d", taxincluded);
   760     if (entry->b_taxincluded == taxincluded) {
   761          LEAVE (
"Value already set");
   764     gncEntryBeginEdit (entry);
   765     entry->b_taxincluded = taxincluded;
   766     entry->values_dirty = TRUE;
   768     gncEntryCommitEdit (entry);
   777     if (entry->b_tax_table == 
table) {
   778          LEAVE (
"Value already set");
   781     gncEntryBeginEdit (entry);
   782     if (entry->b_tax_table)
   783         gncTaxTableDecRef (entry->b_tax_table);
   785         gncTaxTableIncRef (
table);
   786     entry->b_tax_table = 
table;
   787     entry->values_dirty = TRUE;
   789     gncEntryCommitEdit (entry);
   793 void gncEntrySetBillable (GncEntry *entry, gboolean billable)
   796     if (entry->billable == billable) 
return;
   798     gncEntryBeginEdit (entry);
   799     entry->billable = billable;
   801     gncEntryCommitEdit (entry);
   804 void gncEntrySetBillTo (GncEntry *entry, 
GncOwner *billto)
   806     if (!entry || !billto) 
return;
   809     gncEntryBeginEdit (entry);
   810     gncOwnerCopy (billto, &entry->billto);
   812     gncEntryCommitEdit (entry);
   815 void gncEntrySetBillPayment (GncEntry *entry, GncEntryPaymentType type)
   818     if (entry->b_payment == type) 
return;
   819     gncEntryBeginEdit (entry);
   820     entry->b_payment = type;
   822     gncEntryCommitEdit (entry);
   826 void gncEntrySetOrder (GncEntry *entry, GncOrder *order)
   829     if (entry->order == order) 
return;
   830     gncEntryBeginEdit (entry);
   831     entry->order = order;
   833     gncEntryCommitEdit (entry);
   838 void gncEntrySetInvoice (GncEntry *entry, GncInvoice *invoice)
   841     if (entry->invoice == invoice) 
return;
   842     gncEntryBeginEdit (entry);
   843     entry->invoice = invoice;
   845     gncEntryCommitEdit (entry);
   849 void gncEntrySetBill (GncEntry *entry, GncInvoice *bill)
   852     if (entry->bill == bill) 
return;
   853     gncEntryBeginEdit (entry);
   856     gncEntryCommitEdit (entry);
   859 void gncEntryCopy (
const GncEntry *src, GncEntry *dest, gboolean add_entry)
   861     if (!src || !dest) 
return;
   863     gncEntryBeginEdit (dest);
   864     dest->date          = src->date;
   865     dest->date_entered      = src->date_entered; 
   866     gncEntrySetDescription (dest, src->desc);
   867     gncEntrySetAction (dest, src->action);
   868     gncEntrySetNotes (dest, src->notes);
   869     dest->quantity      = src->quantity;
   871     dest->i_account     = src->i_account;
   872     dest->i_price           = src->i_price;
   873     dest->i_taxable     = src->i_taxable;
   874     dest->i_taxincluded     = src->i_taxincluded;
   875     dest->i_discount        = src->i_discount;
   876     dest->i_disc_type       = src->i_disc_type;
   877     dest->i_disc_how        = src->i_disc_how;
   880     dest->b_account     = src->b_account;
   881     dest->b_price           = src->b_price;
   882     dest->b_taxable     = src->b_taxable;
   883     dest->b_taxincluded     = src->b_taxincluded;
   884     dest->billable      = src->billable;
   885     dest->billto            = src->billto;
   887     if (src->i_tax_table)
   888         gncEntrySetInvTaxTable (dest, src->i_tax_table);
   890     if (src->b_tax_table)
   891         gncEntrySetBillTaxTable (dest, src->b_tax_table);
   896             gncOrderAddEntry (src->order, dest);
   899             gncInvoiceAddEntry (src->invoice, dest);
   905     dest->values_dirty = TRUE;
   907     gncEntryCommitEdit (dest);
   915     return entry ? entry->date : 0;
   923 time64 gncEntryGetDateEntered (
const GncEntry *entry)
   925     return entry ? entry->date_entered : 0;
   928 const char * gncEntryGetDescription (
const GncEntry *entry)
   930     if (!entry) 
return NULL;
   934 const char * gncEntryGetAction (
const GncEntry *entry)
   936     if (!entry) 
return NULL;
   937     return entry->action;
   940 const char * gncEntryGetNotes (
const GncEntry *entry)
   942     if (!entry) 
return NULL;
   948     if (!entry) 
return gnc_numeric_zero();
   949     return entry->quantity;
   960 Account * gncEntryGetInvAccount (
const GncEntry *entry)
   962     if (!entry) 
return NULL;
   963     return entry->i_account;
   966 gnc_numeric gncEntryGetInvPrice (
const GncEntry *entry)
   968     if (!entry) 
return gnc_numeric_zero();
   969     return entry->i_price;
   972 gnc_numeric gncEntryGetInvDiscount (
const GncEntry *entry)
   974     if (!entry) 
return gnc_numeric_zero();
   975     return entry->i_discount;
   978 GncAmountType gncEntryGetInvDiscountType (
const GncEntry *entry)
   980     if (!entry) 
return 0;
   981     return entry->i_disc_type;
   984 GncDiscountHow gncEntryGetInvDiscountHow (
const GncEntry *entry)
   986     if (!entry) 
return 0;
   987     return entry->i_disc_how;
   990 char* qofEntryGetInvDiscType (
const GncEntry *entry)
   994     if (!entry) 
return 0;
   995     type_string = g_strdup(gncAmountTypeToString(entry->i_disc_type));
   999 char* qofEntryGetInvDiscHow (
const GncEntry *entry)
  1003     if (!entry) 
return 0;
  1008 gboolean gncEntryGetInvTaxable (
const GncEntry *entry)
  1010     if (!entry) 
return FALSE;
  1011     return entry->i_taxable;
  1014 gboolean gncEntryGetInvTaxIncluded (
const GncEntry *entry)
  1016     if (!entry) 
return FALSE;
  1017     return entry->i_taxincluded;
  1020 GncTaxTable * gncEntryGetInvTaxTable (
const GncEntry *entry)
  1022     if (!entry) 
return NULL;
  1023     return entry->i_tax_table;
  1028 Account * gncEntryGetBillAccount (
const GncEntry *entry)
  1030     if (!entry) 
return NULL;
  1031     return entry->b_account;
  1034 gnc_numeric gncEntryGetBillPrice (
const GncEntry *entry)
  1036     if (!entry) 
return gnc_numeric_zero();
  1037     return entry->b_price;
  1040 gboolean gncEntryGetBillTaxable (
const GncEntry *entry)
  1042     if (!entry) 
return FALSE;
  1043     return entry->b_taxable;
  1046 gboolean gncEntryGetBillTaxIncluded (
const GncEntry *entry)
  1048     if (!entry) 
return FALSE;
  1049     return entry->b_taxincluded;
  1052 GncTaxTable * gncEntryGetBillTaxTable (
const GncEntry *entry)
  1054     if (!entry) 
return NULL;
  1055     return entry->b_tax_table;
  1058 gboolean gncEntryGetBillable (
const GncEntry *entry)
  1060     if (!entry) 
return FALSE;
  1061     return entry->billable;
  1064 GncOwner * gncEntryGetBillTo (GncEntry *entry)
  1066     if (!entry) 
return NULL;
  1067     return &entry->billto;
  1070 GncEntryPaymentType gncEntryGetBillPayment (
const GncEntry* entry)
  1072     if (!entry) 
return 0;
  1073     return entry->b_payment;
  1076 GncInvoice * gncEntryGetInvoice (
const GncEntry *entry)
  1078     if (!entry) 
return NULL;
  1079     return entry->invoice;
  1082 GncInvoice * gncEntryGetBill (
const GncEntry *entry)
  1084     if (!entry) 
return NULL;
  1088 GncOrder * gncEntryGetOrder (
const GncEntry *entry)
  1090     if (!entry) 
return NULL;
  1091     return entry->order;
  1131 static void gncEntryComputeValueInt (gnc_numeric qty, gnc_numeric price,
  1132                     const GncTaxTable *tax_table, gboolean tax_included,
  1134                     GncDiscountHow discount_how,
  1135                     gnc_numeric *value, gnc_numeric *discount_value,
  1136                     GList **tax_value, gnc_numeric *net_price)
  1138     gnc_numeric aggregate;
  1142     gnc_numeric percent = gnc_numeric_create (100, 1);
  1143     gnc_numeric tpercent = gnc_numeric_zero ();
  1144     gnc_numeric tvalue = gnc_numeric_zero ();
  1145     gnc_numeric i_net_price = price;
  1147     GList     * entries = gncTaxTableGetEntries (tax_table);
  1155     PINFO (
"Aggregate value %" PRId64 
"/%" PRId64, aggregate.num, aggregate.denom);
  1159     for (node = entries; node; node = node->next)
  1162         gnc_numeric amount = gncTaxTableEntryGetAmount (entry);
  1164         switch (gncTaxTableEntryGetType (entry))
  1175             PWARN (
"Unknown tax type: %d", gncTaxTableEntryGetType (entry));
  1182     PINFO(
"Tax rate %" PRId64 
"/%" PRId64, tpercent.num, tpercent.denom);
  1186     if (tax_table && tax_included)
  1196                                           gnc_numeric_create (1, 1),
  1199         PINFO (
"pretax %" PRId64 
"/%" PRId64, pretax.num, pretax.denom);
  1204         PINFO(
"i_net_price %" PRId64 
"/%" PRId64, i_net_price.num, i_net_price.denom);
  1208         PINFO (
"Tax not included or no tax table, pretax is aggregate");
  1231     switch (discount_how)
  1233     case GNC_DISC_PRETAX:
  1234     case GNC_DISC_SAMETIME:
  1248         if (discount_how == GNC_DISC_PRETAX)
  1252     case GNC_DISC_POSTTAX:
  1257             gnc_numeric after_tax;
  1273         PWARN (
"unknown DiscountHow value: %d", discount_how);
  1284     if (discount_value != NULL)
  1285         *discount_value = discount;
  1292     if (tax_value != NULL)
  1294         GList * taxes = NULL;
  1296         PINFO(
"Computing tax value list");
  1297         for (node = entries; node; node = node->next)
  1300             Account *acc = gncTaxTableEntryGetAccount (entry);
  1301             gnc_numeric amount = gncTaxTableEntryGetAmount (entry);
  1303             g_return_if_fail (acc);
  1305             switch (gncTaxTableEntryGetType (entry))
  1323     if (net_price != NULL)
  1324       *net_price = i_net_price;
  1331                            const GncTaxTable *tax_table, gboolean tax_included,
  1333                            GncDiscountHow discount_how, G_GNUC_UNUSED 
int SCU,
  1334                            gnc_numeric *value, gnc_numeric *discount_value,
  1337   gncEntryComputeValueInt (qty, price, tax_table, tax_included, discount, discount_type,
  1338                discount_how, value, discount_value, tax_value, NULL);
  1342 get_entry_commodity_denom (
const GncEntry *entry)
  1349         c = gncInvoiceGetCurrency (entry->invoice);
  1355         c = gncInvoiceGetCurrency (entry->bill);
  1363 gncEntryRecomputeValues (GncEntry *entry)
  1370     if (entry->i_tax_table)
  1372         time64 modtime = gncTaxTableLastModifiedSecs (entry->i_tax_table);
  1373         if (entry->i_taxtable_modtime != modtime)
  1375             PINFO (
"Invoice tax table changed since last recompute.");
  1376             entry->values_dirty = TRUE;
  1377             entry->i_taxtable_modtime = modtime;
  1380     if (entry->b_tax_table)
  1382         time64 modtime = gncTaxTableLastModifiedSecs (entry->b_tax_table);
  1383         if (entry->b_taxtable_modtime != modtime)
  1385             PINFO (
"Bill tax table changed since last recompute.");
  1386             entry->values_dirty = TRUE;
  1387             entry->b_taxtable_modtime = modtime;
  1391     if (!entry->values_dirty) {
  1392         LEAVE (
"No changes");
  1397     if (entry->i_tax_values)
  1400         entry->i_tax_values = NULL;
  1402     if (entry->b_tax_values)
  1405         entry->b_tax_values = NULL;
  1409     denom = get_entry_commodity_denom (entry);
  1412     DEBUG(
"Compute Invoice Values.");
  1414                           (entry->i_taxable ? entry->i_tax_table : NULL),
  1415                           entry->i_taxincluded,
  1416                           entry->i_discount, entry->i_disc_type,
  1419                           &(entry->i_value), &(entry->i_disc_value),
  1420                           &(entry->i_tax_values));
  1423     DEBUG(
"Compute BILL Values.");
  1425                           (entry->b_taxable ? entry->b_tax_table : NULL),
  1426                           entry->b_taxincluded,
  1429                           &(entry->b_value), NULL, &(entry->b_tax_values));
  1436     entry->i_tax_value_rounded = gnc_numeric_zero();
  1437     for (tv_iter = entry->i_tax_values; tv_iter; tv_iter=tv_iter->next)
  1439         GncAccountValue *acc_val = tv_iter->data;
  1440         entry->i_tax_value_rounded = 
gnc_numeric_add (entry->i_tax_value_rounded, acc_val->value,
  1447     entry->b_tax_value_rounded = gnc_numeric_zero();
  1448     for (tv_iter = entry->b_tax_values; tv_iter; tv_iter=tv_iter->next)
  1450         GncAccountValue *acc_val = tv_iter->data;
  1451         entry->b_tax_value_rounded = 
gnc_numeric_add (entry->b_tax_value_rounded, acc_val->value,
  1454     entry->values_dirty = FALSE;
  1460 static gnc_numeric gncEntryGetIntValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
  1462     if (!entry) 
return gnc_numeric_zero();
  1463     gncEntryRecomputeValues (entry);
  1465         return (is_cust_doc ? entry->i_value_rounded : entry->b_value_rounded);
  1467         return (is_cust_doc ? entry->i_value : entry->b_value);
  1470 static gnc_numeric gncEntryGetIntTaxValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
  1472     if (!entry) 
return gnc_numeric_zero();
  1473     gncEntryRecomputeValues (entry);
  1475         return (is_cust_doc ? entry->i_tax_value_rounded : entry->b_tax_value_rounded);
  1477         return (is_cust_doc ? entry->i_tax_value : entry->b_tax_value);
  1481 static AccountValueList * gncEntryGetIntTaxValues (GncEntry *entry, gboolean is_cust_doc)
  1483     if (!entry) 
return NULL;
  1484     gncEntryRecomputeValues (entry);
  1485     return (is_cust_doc ? entry->i_tax_values : entry->b_tax_values);
  1488 static gnc_numeric gncEntryGetIntDiscountValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
  1490     if (!entry) 
return gnc_numeric_zero();
  1491     gncEntryRecomputeValues (entry);
  1493         return (is_cust_doc ? entry->i_disc_value_rounded : gnc_numeric_zero());
  1495         return (is_cust_doc ? entry->i_disc_value : gnc_numeric_zero());
  1502 gnc_numeric gncEntryGetPrice (
const GncEntry *entry, gboolean cust_doc, gboolean net)
  1507     if (!entry) 
return gnc_numeric_zero();
  1508     if (!net) 
return (cust_doc ? entry->i_price : entry->b_price);
  1513         gncEntryComputeValueInt (entry->quantity, entry->i_price,
  1514                                  (entry->i_taxable ? entry->i_tax_table : NULL),
  1515                                  entry->i_taxincluded,
  1516                                  entry->i_discount, entry->i_disc_type,
  1518                                  NULL, NULL, NULL, &result);
  1520         gncEntryComputeValueInt (entry->quantity, entry->b_price,
  1521                                  (entry->b_taxable ? entry->b_tax_table : NULL),
  1522                                  entry->b_taxincluded,
  1524                                  NULL, NULL, NULL, &result);
  1527     denom = get_entry_commodity_denom (entry);
  1535 gnc_numeric gncEntryGetDocValue (GncEntry *entry, gboolean round, gboolean is_cust_doc, gboolean is_cn)
  1537     gnc_numeric value = gncEntryGetIntValue (entry, round, is_cust_doc);
  1541 gnc_numeric gncEntryGetDocTaxValue (GncEntry *entry, gboolean round, gboolean is_cust_doc, gboolean is_cn)
  1543     gnc_numeric value = gncEntryGetIntTaxValue (entry, round, is_cust_doc);
  1550     AccountValueList *int_values = gncEntryGetIntTaxValues (entry, is_cust_doc);
  1551     AccountValueList *values = NULL, *node;
  1554     for (node = int_values; node; node = node->next)
  1556         GncAccountValue *acct_val = node->data;
  1559                                       : acct_val->value));
  1565 gnc_numeric gncEntryGetDocDiscountValue (GncEntry *entry, gboolean round, gboolean is_cust_doc, gboolean is_cn)
  1567     gnc_numeric value = gncEntryGetIntDiscountValue (entry, round, is_cust_doc);
  1571 gnc_numeric gncEntryGetBalValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
  1573     gnc_numeric value = gncEntryGetIntValue (entry, round, is_cust_doc);
  1577 gnc_numeric gncEntryGetBalTaxValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
  1579     gnc_numeric value = gncEntryGetIntTaxValue (entry, round, is_cust_doc);
  1586     AccountValueList *int_values = gncEntryGetIntTaxValues (entry, is_cust_doc);
  1587     AccountValueList *values = NULL, *node;
  1590     for (node = int_values; node; node = node->next)
  1592         GncAccountValue *acct_val = node->data;
  1595                                       : acct_val->value));
  1601 gnc_numeric gncEntryGetBalDiscountValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
  1603     gnc_numeric value = gncEntryGetIntDiscountValue (entry, round, is_cust_doc);
  1608 gboolean gncEntryIsOpen (
const GncEntry *entry)
  1610     if (!entry) 
return FALSE;
  1611     return (qof_instance_get_editlevel(entry) > 0);
  1616 void gncEntryBeginEdit (GncEntry *entry)
  1623     PERR(
"Entry QofBackend Failure: %d", errcode);
  1624     gnc_engine_signal_commit_error( errcode );
  1631     GncEntry *entry = (GncEntry *)inst;
  1632     gncEntryFree (entry);
  1635 void gncEntryCommitEdit (GncEntry *entry)
  1640                                GNC_FEATURE_KVP_EXTRA_DATA);
  1644                            gncEntryOnDone, entry_free);
  1647 int gncEntryCompare (
const GncEntry *a, 
const GncEntry *b)
  1651     if (a == b) 
return 0;
  1652     if (!a && b) 
return -1;
  1653     if (a && !b) 
return 1;
  1655     if (a->date != b->date) 
return a->date - b->date;
  1656     if (a->date_entered != b->date_entered) 
return a->date_entered - b->date_entered;
  1658     compare = g_strcmp0 (a->desc, b->desc);
  1659     if (compare) 
return compare;
  1661     compare = g_strcmp0 (a->action, b->action);
  1662     if (compare) 
return compare;
  1667 #define CHECK_STRING(X, Y, FIELD) \  1668     if (g_strcmp0((X)->FIELD, (Y)->FIELD) != 0) \  1670         PWARN("%s differ: %s vs %s", #FIELD, (X)->FIELD, (Y)->FIELD); \  1674 #define CHECK_ACCOUNT(X, Y, FIELD) \  1675     if (!xaccAccountEqual((X)->FIELD, (Y)->FIELD, TRUE)) \  1677         PWARN("%s differ", #FIELD); \  1681 #define CHECK_NUMERIC(X, Y, FIELD) \  1682     if (!gnc_numeric_equal((X)->FIELD, (Y)->FIELD)) \  1684         PWARN("%s differ", #FIELD); \  1688 #define CHECK_VALUE(X, Y, FIELD) \  1689     if ((X)->FIELD != (Y)->FIELD) \  1691         PWARN("%s differ", #FIELD); \  1700 destroy_entry_on_book_close(
QofInstance *ent, gpointer data)
  1702     GncEntry* entry = GNC_ENTRY(ent);
  1704     gncEntryBeginEdit(entry);
  1705     gncEntryDestroy(entry);
  1713 gnc_entry_book_end(QofBook* book)
  1718     qof_collection_foreach(col, destroy_entry_on_book_close, NULL);
  1721 static QofObject gncEntryDesc =
  1724     DI(.e_type            = ) _GNC_MOD_NAME,
  1725     DI(.type_label        = ) "Order/Invoice/Bill Entry",
  1726     DI(.create            = ) (gpointer)gncEntryCreate,
  1727     DI(.book_begin        = ) NULL,
  1728     DI(.book_end          = ) gnc_entry_book_end,
  1731     DI(.foreach           = ) qof_collection_foreach,
  1732     DI(.printable         = ) NULL,
  1736 gboolean gncEntryRegister (
void)
  1738     static QofParam params[] =
  1748         { ENTRY_INVOICE, GNC_ID_INVOICE, (
QofAccessFunc)gncEntryGetInvoice, NULL },
  1751         { ENTRY_BILL, GNC_ID_INVOICE, (
QofAccessFunc)gncEntryGetBill, NULL },
  1753             ENTRY_INV_DISC_TYPE, QOF_TYPE_STRING, (
QofAccessFunc)qofEntryGetInvDiscType,
  1757             ENTRY_INV_DISC_HOW, QOF_TYPE_STRING, (
QofAccessFunc)qofEntryGetInvDiscHow,
  1761             ENTRY_INV_TAXABLE, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncEntryGetInvTaxable,
  1765             ENTRY_INV_TAX_INC, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncEntryGetInvTaxIncluded,
  1769             ENTRY_BILL_TAXABLE, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncEntryGetBillTaxable,
  1773             ENTRY_BILL_TAX_INC, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncEntryGetBillTaxIncluded,
  1778         { ENTRY_ORDER, GNC_ID_ORDER, (
QofAccessFunc)gncEntryGetOrder, NULL },
 int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times. 
Never round at all, and signal an error if there is a fractional result in a computation. 
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity. 
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance. 
void gncEntrySetQuantity(GncEntry *entry, gnc_numeric quantity)
Set the internal quantity without any conversion. 
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. 
#define PINFO(format, args...)
Print an informational note. 
QofBackendError
The errors that can be reported to the GUI & other front-end users. 
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
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 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 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. 
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0. 
GDate time64_to_gdate(time64 t)
Returns the GDate in which the time64 occurs. 
QofCollection * qof_instance_get_collection(gconstpointer ptr)
Return the collection this instance belongs to. 
gnc_numeric gncAccountValueTotal(GList *list)
return the total for this list 
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. 
void gncInvoiceSortEntries(GncInvoice *invoice)
Call this function when an Entry is changed and you want to re-sort the list of entries. 
void gncEntrySetDocQuantity(GncEntry *entry, gnc_numeric quantity, gboolean is_cn)
Set the internal quantity converting from the quantity as visible on the physical document...
#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(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters. 
time64 gncEntryGetDate(const GncEntry *entry)
DEPRECATED - use gncEntryGetDateGDate() instead! (Because the time-of-day is a misleading extra infor...
#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 
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 ...
AccountValueList * gncEntryGetBalTaxValues(GncEntry *entry, gboolean is_cust_doc)
Careful: the returned list is NOT owned by the entry and should be freed by the caller. 
Reduce the result value by common factor elimination, using the smallest possible value for the denom...
void gncEntryComputeValue(gnc_numeric qty, gnc_numeric price, const GncTaxTable *tax_table, gboolean tax_included, gnc_numeric discount, GncAmountType discount_type, GncDiscountHow discount_how, int SCU, gnc_numeric *value, gnc_numeric *discount_value, GList **tax_values)
Compute the Entry value, tax_value, and discount_value, based on the quantity, price, discount, tax_-table, and types. 
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product. 
void gncBillAddEntry(GncInvoice *bill, GncEntry *entry)
Call this function when adding an entry to a bill instead of an invoice. 
GDate gncEntryGetDateGDate(const GncEntry *entry)
Returns the day of this entry. 
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 
void gncEntrySetDateGDate(GncEntry *entry, const GDate *date)
Set the date of this entry. 
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 
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 gnc_numeric_eq(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b are exactly the same (have the same numerator and ...
const char * gncEntryDiscountHowToString(GncDiscountHow how)
How to apply the discount and taxes. 
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b. 
Business Invoice Interface. 
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances. 
gnc_numeric gncEntryGetQuantity(const GncEntry *entry)
Get the quantity as stored internally. 
#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...
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...
void gncEntrySetDate(GncEntry *entry, time64 date)
DEPRECATED - use gncEntrySetDateGDate() instead! (Because the time-of-day is a misleading extra infor...
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. 
Use unbiased ("banker's") rounding. 
Business Entry Interface. 
time64 time64CanonicalDayTime(time64 t)
convert a time64 on a certain day (localtime) to the time64 representing midday on that day...
gboolean qof_instance_has_kvp(QofInstance *inst)
Report whether a QofInstance has anything stored in KVP. 
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. 
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument. 
GncAmountType
How to interpret the amount. 
gnc_numeric gncEntryGetDocQuantity(const GncEntry *entry, gboolean is_cn)
Get the quantity as on the physical document. 
Commodity handling public routines. 
modtime is the internal date of the last modtime See libgnucash/engine/TaxTableBillTermImmutability.txt for an explanation of the following Code that handles refcount, parent, child, invisible and children is identical to that in ::GncBillTerm 
gchar * qof_instance_get_display_name(const QofInstance *inst)
Returns a displayable name for this object. 
Utility functions for file access.