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 a, gnc_numeric b, 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.