31#include <qofinstance-p.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;
107static 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);
132gboolean 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)");
157const 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);
174gboolean 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); \
200static inline void mark_entry (GncEntry *entry);
201void mark_entry (GncEntry *entry)
203 qof_instance_set_dirty(&entry->inst);
241G_DEFINE_TYPE(GncEntry, gnc_entry, QOF_TYPE_INSTANCE)
244gnc_entry_init(GncEntry* entry)
249gnc_entry_dispose(GObject *entryp)
251 G_OBJECT_CLASS(gnc_entry_parent_class)->dispose(entryp);
255gnc_entry_finalize(GObject* entryp)
257 G_OBJECT_CLASS(gnc_entry_parent_class)->finalize(entryp);
261gnc_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);
283gnc_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))
386gnc_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 "
413GncEntry *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;
446void gncEntryDestroy (GncEntry *entry)
449 qof_instance_set_destroying(entry, TRUE);
450 gncEntryCommitEdit(entry);
453static 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))
517void gncEntrySetDateEntered (GncEntry *entry,
time64 date)
520 if (entry->date_entered == date)
return;
521 gncEntryBeginEdit (entry);
522 entry->date_entered = date;
524 gncEntryCommitEdit (entry);
527void gncEntrySetDescription (GncEntry *entry,
const char *desc)
529 if (!entry || !desc)
return;
530 SET_STR (entry, entry->desc, desc);
532 gncEntryCommitEdit (entry);
535void gncEntrySetAction (GncEntry *entry,
const char *action)
537 if (!entry || !action)
return;
538 SET_STR (entry, entry->action, action);
540 gncEntryCommitEdit (entry);
543void 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);
575void gncEntrySetInvAccount (GncEntry *entry,
Account *acc)
578 if (entry->i_account == acc)
return;
579 gncEntryBeginEdit (entry);
580 entry->i_account = acc;
582 gncEntryCommitEdit (entry);
585void gncEntrySetInvPrice (GncEntry *entry, gnc_numeric price)
589 gncEntryBeginEdit (entry);
590 entry->i_price = price;
591 entry->values_dirty = TRUE;
593 gncEntryCommitEdit (entry);
596void 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);
613void 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);
651void gncEntrySetInvDiscount (GncEntry *entry, gnc_numeric discount)
655 gncEntryBeginEdit (entry);
656 entry->i_discount = discount;
657 entry->values_dirty = TRUE;
659 gncEntryCommitEdit (entry);
662void 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);
674void 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);
686void 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);
701void 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);
717void gncEntrySetBillAccount (GncEntry *entry,
Account *acc)
720 if (entry->b_account == acc)
return;
721 gncEntryBeginEdit (entry);
722 entry->b_account = acc;
724 gncEntryCommitEdit (entry);
727void gncEntrySetBillPrice (GncEntry *entry, gnc_numeric price)
731 gncEntryBeginEdit (entry);
732 entry->b_price = price;
733 entry->values_dirty = TRUE;
735 gncEntryCommitEdit (entry);
738void 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);
755void 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);
793void gncEntrySetBillable (GncEntry *entry, gboolean billable)
796 if (entry->billable == billable)
return;
798 gncEntryBeginEdit (entry);
799 entry->billable = billable;
801 gncEntryCommitEdit (entry);
804void gncEntrySetBillTo (GncEntry *entry,
GncOwner *billto)
806 if (!entry || !billto)
return;
809 gncEntryBeginEdit (entry);
810 gncOwnerCopy (billto, &entry->billto);
812 gncEntryCommitEdit (entry);
815void gncEntrySetBillPayment (GncEntry *entry, GncEntryPaymentType type)
818 if (entry->b_payment == type)
return;
819 gncEntryBeginEdit (entry);
820 entry->b_payment = type;
822 gncEntryCommitEdit (entry);
826void gncEntrySetOrder (GncEntry *entry, GncOrder *order)
829 if (entry->order == order)
return;
830 gncEntryBeginEdit (entry);
831 entry->order = order;
833 gncEntryCommitEdit (entry);
838void gncEntrySetInvoice (GncEntry *entry, GncInvoice *invoice)
841 if (entry->invoice == invoice)
return;
842 gncEntryBeginEdit (entry);
843 entry->invoice = invoice;
845 gncEntryCommitEdit (entry);
849void gncEntrySetBill (GncEntry *entry, GncInvoice *bill)
852 if (entry->bill == bill)
return;
853 gncEntryBeginEdit (entry);
856 gncEntryCommitEdit (entry);
859void 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;
923time64 gncEntryGetDateEntered (
const GncEntry *entry)
925 return entry ? entry->date_entered : 0;
928const char * gncEntryGetDescription (
const GncEntry *entry)
930 if (!entry)
return NULL;
934const char * gncEntryGetAction (
const GncEntry *entry)
936 if (!entry)
return NULL;
937 return entry->action;
940const char * gncEntryGetNotes (
const GncEntry *entry)
942 if (!entry)
return NULL;
948 if (!entry)
return gnc_numeric_zero();
949 return entry->quantity;
960Account * gncEntryGetInvAccount (
const GncEntry *entry)
962 if (!entry)
return NULL;
963 return entry->i_account;
966gnc_numeric gncEntryGetInvPrice (
const GncEntry *entry)
968 if (!entry)
return gnc_numeric_zero();
969 return entry->i_price;
972gnc_numeric gncEntryGetInvDiscount (
const GncEntry *entry)
974 if (!entry)
return gnc_numeric_zero();
975 return entry->i_discount;
978GncAmountType gncEntryGetInvDiscountType (
const GncEntry *entry)
980 if (!entry)
return 0;
981 return entry->i_disc_type;
984GncDiscountHow gncEntryGetInvDiscountHow (
const GncEntry *entry)
986 if (!entry)
return 0;
987 return entry->i_disc_how;
990char* qofEntryGetInvDiscType (
const GncEntry *entry)
994 if (!entry)
return 0;
995 type_string = g_strdup(gncAmountTypeToString(entry->i_disc_type));
999char* qofEntryGetInvDiscHow (
const GncEntry *entry)
1003 if (!entry)
return 0;
1008gboolean gncEntryGetInvTaxable (
const GncEntry *entry)
1010 if (!entry)
return FALSE;
1011 return entry->i_taxable;
1014gboolean gncEntryGetInvTaxIncluded (
const GncEntry *entry)
1016 if (!entry)
return FALSE;
1017 return entry->i_taxincluded;
1020GncTaxTable * gncEntryGetInvTaxTable (
const GncEntry *entry)
1022 if (!entry)
return NULL;
1023 return entry->i_tax_table;
1028Account * gncEntryGetBillAccount (
const GncEntry *entry)
1030 if (!entry)
return NULL;
1031 return entry->b_account;
1034gnc_numeric gncEntryGetBillPrice (
const GncEntry *entry)
1036 if (!entry)
return gnc_numeric_zero();
1037 return entry->b_price;
1040gboolean gncEntryGetBillTaxable (
const GncEntry *entry)
1042 if (!entry)
return FALSE;
1043 return entry->b_taxable;
1046gboolean gncEntryGetBillTaxIncluded (
const GncEntry *entry)
1048 if (!entry)
return FALSE;
1049 return entry->b_taxincluded;
1052GncTaxTable * gncEntryGetBillTaxTable (
const GncEntry *entry)
1054 if (!entry)
return NULL;
1055 return entry->b_tax_table;
1058gboolean gncEntryGetBillable (
const GncEntry *entry)
1060 if (!entry)
return FALSE;
1061 return entry->billable;
1064GncOwner * gncEntryGetBillTo (GncEntry *entry)
1066 if (!entry)
return NULL;
1067 return &entry->billto;
1070GncEntryPaymentType gncEntryGetBillPayment (
const GncEntry* entry)
1072 if (!entry)
return 0;
1073 return entry->b_payment;
1076GncInvoice * gncEntryGetInvoice (
const GncEntry *entry)
1078 if (!entry)
return NULL;
1079 return entry->invoice;
1082GncInvoice * gncEntryGetBill (
const GncEntry *entry)
1084 if (!entry)
return NULL;
1088GncOrder * gncEntryGetOrder (
const GncEntry *entry)
1090 if (!entry)
return NULL;
1091 return entry->order;
1131static 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));
1181 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_NEVER);
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:
1237 if (discount_type == GNC_AMT_TYPE_PERCENT)
1240 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_NEVER);
1242 GNC_HOW_DENOM_REDUCE | GNC_HOW_RND_ROUND);
1248 if (discount_how == GNC_DISC_PRETAX)
1252 case GNC_DISC_POSTTAX:
1255 if (discount_type == GNC_AMT_TYPE_PERCENT)
1257 gnc_numeric after_tax;
1264 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_NEVER);
1266 GNC_HOW_DENOM_REDUCE | GNC_HOW_RND_ROUND);
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))
1312 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_NEVER);
1323 if (net_price != NULL)
1324 *net_price = i_net_price;
1330void gncEntryComputeValue (gnc_numeric qty, gnc_numeric 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);
1342get_entry_commodity_denom (
const GncEntry *entry)
1349 c = gncInvoiceGetCurrency (entry->invoice);
1355 c = gncInvoiceGetCurrency (entry->bill);
1363gncEntryRecomputeValues (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.");
1413 gncEntryComputeValue (entry->quantity, entry->i_price,
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.");
1424 gncEntryComputeValue (entry->quantity, entry->b_price,
1425 (entry->b_taxable ? entry->b_tax_table : NULL),
1426 entry->b_taxincluded,
1429 &(entry->b_value), NULL, &(entry->b_tax_values));
1431 entry->i_value_rounded = gnc_numeric_convert (entry->i_value, denom,
1432 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
1433 entry->i_disc_value_rounded = gnc_numeric_convert (entry->i_disc_value, denom,
1434 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
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,
1441 denom, GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
1444 entry->b_value_rounded = gnc_numeric_convert (entry->b_value, denom,
1445 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
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,
1452 denom, GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
1454 entry->values_dirty = FALSE;
1460static 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);
1470static 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);
1481static 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);
1488static 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());
1502gnc_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);
1529 result = gnc_numeric_convert (result, denom,
1530 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
1535gnc_numeric gncEntryGetDocValue (GncEntry *entry, gboolean round, gboolean is_cust_doc, gboolean is_cn)
1537 gnc_numeric value = gncEntryGetIntValue (entry, round, is_cust_doc);
1541gnc_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));
1565gnc_numeric gncEntryGetDocDiscountValue (GncEntry *entry, gboolean round, gboolean is_cust_doc, gboolean is_cn)
1567 gnc_numeric value = gncEntryGetIntDiscountValue (entry, round, is_cust_doc);
1571gnc_numeric gncEntryGetBalValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
1573 gnc_numeric value = gncEntryGetIntValue (entry, round, is_cust_doc);
1577gnc_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));
1601gnc_numeric gncEntryGetBalDiscountValue (GncEntry *entry, gboolean round, gboolean is_cust_doc)
1603 gnc_numeric value = gncEntryGetIntDiscountValue (entry, round, is_cust_doc);
1608gboolean gncEntryIsOpen (
const GncEntry *entry)
1610 if (!entry)
return FALSE;
1611 return (qof_instance_get_editlevel(entry) > 0);
1616void 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);
1635void gncEntryCommitEdit (GncEntry *entry)
1640 GNC_FEATURE_KVP_EXTRA_DATA);
1644 gncEntryOnDone, entry_free);
1647int 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); \
1700destroy_entry_on_book_close(
QofInstance *ent, gpointer data)
1702 GncEntry* entry = GNC_ENTRY(ent);
1704 gncEntryBeginEdit(entry);
1705 gncEntryDestroy(entry);
1713gnc_entry_book_end(
QofBook* book)
1718 qof_collection_foreach(col, destroy_entry_on_book_close, NULL);
1721static 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,
1736gboolean 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 },
Commodity handling public routines.
Utility functions for file access.
Business Entry Interface.
Business Invoice Interface.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
gboolean qof_book_shutting_down(const QofBook *book)
Is the book shutting down?
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
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.
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
GDate time64_to_gdate(time64 t)
Returns the GDate in which the time64 occurs.
time64 time64CanonicalDayTime(time64 t)
convert a time64 on a certain day (localtime) to the time64 representing midday on that day.
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of 'dirty' flag on collection.
GDate gncEntryGetDateGDate(const GncEntry *entry)
Returns the day of this entry.
void gncEntrySetDocQuantity(GncEntry *entry, gnc_numeric quantity, gboolean is_cn)
Set the internal quantity converting from the quantity as visible on the physical document.
time64 gncEntryGetDate(const GncEntry *entry)
DEPRECATED - use gncEntryGetDateGDate() instead! (Because the time-of-day is a misleading extra infor...
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.
const char * gncEntryDiscountHowToString(GncDiscountHow how)
How to apply the discount and taxes.
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.
void gncEntrySetDateGDate(GncEntry *entry, const GDate *date)
Set the date of this entry.
gnc_numeric gncEntryGetDocQuantity(const GncEntry *entry, gboolean is_cn)
Get the quantity as on the physical document.
void gncEntrySetQuantity(GncEntry *entry, gnc_numeric quantity)
Set the internal quantity without any conversion.
gnc_numeric gncEntryGetQuantity(const GncEntry *entry)
Get the quantity as stored internally.
void gncEntrySetDate(GncEntry *entry, time64 date)
DEPRECATED - use gncEntrySetDateGDate() instead! (Because the time-of-day is a misleading extra infor...
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
QofCollection * qof_instance_get_collection(gconstpointer ptr)
Return the collection this instance belongs to.
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
gchar * qof_instance_get_display_name(const QofInstance *inst)
Returns a displayable name for this object.
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.
void gncInvoiceSortEntries(GncInvoice *invoice)
Call this function when an Entry is changed and you want to re-sort the list of entries.
void gncBillAddEntry(GncInvoice *bill, GncEntry *entry)
Call this function when adding an entry to a bill instead of an invoice.
gboolean qof_instance_has_kvp(QofInstance *inst)
Report whether a QofInstance has anything stored in KVP.
#define PINFO(format, args...)
Print an informational note.
#define DEBUG(format, args...)
Print a debugging message.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define PERR(format, args...)
Log a serious error.
#define PWARN(format, args...)
Log a warning.
#define ENTER(format, args...)
Print a function entry debugging message.
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 ...
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
gboolean gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking.
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
void gncAccountValueDestroy(GList *list)
Destroy a list of accountvalues.
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.
GncAmountType
How to interpret the amount.
gnc_numeric gncAccountValueTotal(GList *list)
return the total for this list
@ GNC_AMT_TYPE_VALUE
tax is a number
@ GNC_AMT_TYPE_PERCENT
tax is a percentage
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
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 qof_commit_edit(QofInstance *inst)
commit_edit helpers
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
modtime is the internal date of the last modtime See libgnucash/engine/TaxTableBillTermImmutability....