35 #include <glib/gi18n.h> 36 #include <qofinstance-p.h> 40 #include "gncBillTermP.h" 42 #include "gncEntryP.h" 46 #include "gncInvoiceP.h" 47 #include "gncOwnerP.h" 48 #include "engine-helpers.h" 58 const char *billing_id;
69 gnc_numeric to_charge_amount;
71 gnc_commodity *currency;
74 Transaction *posted_txn;
80 QofInstanceClass parent_class;
83 static QofLogModule log_module = GNC_MOD_BUSINESS;
85 #define _GNC_MOD_NAME GNC_ID_INVOICE 87 #define GNC_INVOICE_IS_CN "credit-note" 88 #define GNC_INVOICE_DOCLINK "assoc_uri" // this is the old name for the document link, kept for compatibility 90 #define SET_STR(obj, member, str) { \ 91 if (!g_strcmp0 (member, str)) return; \ 92 gncInvoiceBeginEdit (obj); \ 93 CACHE_REPLACE (member, str); \ 96 static void mark_invoice (GncInvoice *invoice);
98 mark_invoice (GncInvoice *invoice)
100 qof_instance_set_dirty (&invoice->inst);
104 QofBook * gncInvoiceGetBook (GncInvoice *x)
133 G_DEFINE_TYPE(GncInvoice, gnc_invoice, QOF_TYPE_INSTANCE)
136 gnc_invoice_init (GncInvoice* inv)
138 inv->date_posted = INT64_MAX;
139 inv->date_opened = INT64_MAX;
143 gnc_invoice_dispose (GObject *invp)
145 G_OBJECT_CLASS(gnc_invoice_parent_class)->dispose(invp);
149 gnc_invoice_finalize (GObject* invp)
151 G_OBJECT_CLASS(gnc_invoice_parent_class)->finalize(invp);
155 gnc_invoice_get_property (GObject *
object,
162 g_return_if_fail (GNC_IS_INVOICE(
object));
164 inv = GNC_INVOICE(
object);
168 g_value_set_string (value, inv->notes);
171 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
177 gnc_invoice_set_property (GObject *
object,
184 g_return_if_fail (GNC_IS_INVOICE(
object));
186 inv = GNC_INVOICE(
object);
187 g_assert (qof_instance_get_editlevel (inv));
192 gncInvoiceSetNotes (inv, g_value_get_string (value));
195 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
208 g_return_val_if_fail (inst != NULL, FALSE);
209 g_return_val_if_fail (GNC_IS_INVOICE(inst), FALSE);
211 inv = GNC_INVOICE(inst);
218 s = g_strdup_printf (
"Invoice %s (%s)", inv->id, display_name);
219 g_free (display_name);
223 s = g_strdup_printf (
"Invoice %s", inv->id);
235 g_return_val_if_fail (inst != NULL, FALSE);
236 g_return_val_if_fail (GNC_IS_INVOICE(inst), FALSE);
238 inv = GNC_INVOICE(inst);
240 if (GNC_IS_BILLTERM(ref))
242 return (inv->terms == GNC_BILLTERM(ref));
244 else if (GNC_IS_JOB(ref))
246 return (inv->job == GNC_JOB(ref));
248 else if (GNC_IS_COMMODITY(ref))
250 return (inv->currency == GNC_COMMODITY(ref));
252 else if (GNC_IS_ACCOUNT(ref))
254 return (inv->posted_acc == GNC_ACCOUNT(ref));
256 else if (GNC_IS_TRANSACTION(ref))
258 return (inv->posted_txn == GNC_TRANSACTION(ref));
260 else if (GNC_IS_LOT(ref))
262 return (inv->posted_lot == GNC_LOT(ref));
277 if (!GNC_IS_BILLTERM(ref) && !GNC_IS_JOB(ref) && !GNC_IS_COMMODITY(ref) && !GNC_IS_ACCOUNT(ref)
278 && !GNC_IS_TRANSACTION(ref) && !GNC_IS_LOT(ref))
287 gnc_invoice_class_init (GncInvoiceClass *klass)
289 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
290 QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
292 gobject_class->dispose = gnc_invoice_dispose;
293 gobject_class->finalize = gnc_invoice_finalize;
294 gobject_class->set_property = gnc_invoice_set_property;
295 gobject_class->get_property = gnc_invoice_get_property;
297 qof_class->get_display_name = impl_get_display_name;
298 qof_class->refers_to_object = impl_refers_to_object;
299 qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
301 g_object_class_install_property
304 g_param_spec_string (
"notes",
306 "The invoice notes is an arbitrary string " 307 "assigned by the user to provide notes regarding " 314 GncInvoice *gncInvoiceCreate (QofBook *book)
318 if (!book)
return NULL;
320 invoice = g_object_new (GNC_TYPE_INVOICE, NULL);
323 invoice->id = CACHE_INSERT (
"");
324 invoice->notes = CACHE_INSERT (
"");
325 invoice->billing_id = CACHE_INSERT (
"");
327 invoice->billto.type = GNC_OWNER_CUSTOMER;
328 invoice->active = TRUE;
330 invoice->to_charge_amount = gnc_numeric_zero ();
342 GValue v = G_VALUE_INIT;
348 invoice = g_object_new (GNC_TYPE_INVOICE, NULL);
351 gncInvoiceBeginEdit (invoice);
353 invoice->id = CACHE_INSERT (from->id);
354 invoice->notes = CACHE_INSERT (from->notes);
355 invoice->billing_id = CACHE_INSERT (from->billing_id);
356 invoice->active = from->active;
359 if (G_VALUE_HOLDS_INT64 (&v))
363 invoice->terms = from->terms;
364 gncBillTermIncRef (invoice->terms);
366 gncOwnerCopy (&from->billto, &invoice->billto);
367 gncOwnerCopy (&from->owner, &invoice->owner);
368 invoice->job = from->job;
370 invoice->to_charge_amount = from->to_charge_amount;
371 invoice->date_opened = from->date_opened;
374 invoice->currency = from->currency;
376 gncInvoiceSetDocLink (invoice, gncInvoiceGetDocLink (from));
379 for (node = from->entries; node; node = node->next)
381 GncEntry *from_entry = node->data;
382 GncEntry *to_entry = gncEntryCreate (book);
383 gncEntryCopy (from_entry, to_entry, FALSE);
385 switch (gncInvoiceGetOwnerType (invoice))
387 case GNC_OWNER_VENDOR:
388 case GNC_OWNER_EMPLOYEE:
392 case GNC_OWNER_CUSTOMER:
395 gncInvoiceAddEntry (invoice, to_entry);
404 mark_invoice (invoice);
405 gncInvoiceCommitEdit (invoice);
410 void gncInvoiceDestroy (GncInvoice *invoice)
412 if (!invoice)
return;
413 qof_instance_set_destroying (invoice, TRUE);
414 gncInvoiceCommitEdit (invoice);
417 static void gncInvoiceFree (GncInvoice *invoice)
419 if (!invoice)
return;
423 CACHE_REMOVE (invoice->id);
424 CACHE_REMOVE (invoice->notes);
425 CACHE_REMOVE (invoice->billing_id);
426 g_list_free (invoice->entries);
427 g_list_free (invoice->prices);
429 if (invoice->printname)
430 g_free (invoice->printname);
435 gncBillTermDecRef (invoice->terms);
439 g_object_unref (invoice);
445 void gncInvoiceSetID (GncInvoice *invoice,
const char *
id)
447 if (!invoice || !
id)
return;
448 SET_STR (invoice, invoice->id,
id);
449 mark_invoice (invoice);
450 gncInvoiceCommitEdit (invoice);
453 void gncInvoiceSetOwner (GncInvoice *invoice,
GncOwner *owner)
455 if (!invoice || !owner)
return;
457 gncInvoiceBeginEdit (invoice);
458 gncOwnerCopy (owner, &invoice->owner);
459 mark_invoice (invoice);
460 gncInvoiceCommitEdit (invoice);
464 qofInvoiceSetOwner (GncInvoice *invoice,
QofInstance *ent)
466 if (!invoice || !ent)
470 gncInvoiceBeginEdit (invoice);
472 mark_invoice (invoice);
473 gncInvoiceCommitEdit (invoice);
477 qofInvoiceSetBillTo (GncInvoice *invoice,
QofInstance *ent)
479 if (!invoice || !ent)
483 gncInvoiceBeginEdit (invoice);
485 mark_invoice (invoice);
486 gncInvoiceCommitEdit (invoice);
495 void gncInvoiceSetDateOpened (GncInvoice *invoice,
time64 date)
497 if (!invoice)
return;
498 if (date == invoice->date_opened)
return;
499 gncInvoiceBeginEdit (invoice);
500 invoice->date_opened = date;
501 mark_invoice (invoice);
502 gncInvoiceCommitEdit (invoice);
505 void gncInvoiceSetDatePosted (GncInvoice *invoice,
time64 date)
507 if (!invoice)
return;
508 if (date == invoice->date_posted)
return;
509 gncInvoiceBeginEdit (invoice);
510 invoice->date_posted = date;
511 mark_invoice (invoice);
512 gncInvoiceCommitEdit (invoice);
515 void gncInvoiceSetTerms (GncInvoice *invoice, GncBillTerm *terms)
517 if (!invoice)
return;
518 if (invoice->terms == terms)
return;
519 gncInvoiceBeginEdit (invoice);
521 gncBillTermDecRef (invoice->terms);
522 invoice->terms = terms;
524 gncBillTermIncRef (invoice->terms);
525 mark_invoice (invoice);
526 gncInvoiceCommitEdit (invoice);
529 void gncInvoiceSetBillingID (GncInvoice *invoice,
const char *billing_id)
531 if (!invoice)
return;
532 SET_STR (invoice, invoice->billing_id, billing_id);
533 mark_invoice (invoice);
534 gncInvoiceCommitEdit (invoice);
537 void gncInvoiceSetNotes (GncInvoice *invoice,
const char *notes)
539 if (!invoice || !notes)
return;
540 SET_STR (invoice, invoice->notes, notes);
541 mark_invoice (invoice);
542 gncInvoiceCommitEdit (invoice);
545 void gncInvoiceSetDocLink (GncInvoice *invoice,
const char *doclink)
547 if (!invoice || !doclink)
return;
549 gncInvoiceBeginEdit (invoice);
551 if (doclink[0] ==
'\0')
557 GValue v = G_VALUE_INIT;
558 g_value_init (&v, G_TYPE_STRING);
559 g_value_set_static_string (&v, doclink);
563 qof_instance_set_dirty (QOF_INSTANCE(invoice));
564 gncInvoiceCommitEdit (invoice);
567 void gncInvoiceSetActive (GncInvoice *invoice, gboolean active)
569 if (!invoice)
return;
570 if (invoice->active == active)
return;
571 gncInvoiceBeginEdit (invoice);
572 invoice->active = active;
573 mark_invoice (invoice);
574 gncInvoiceCommitEdit (invoice);
577 void gncInvoiceSetIsCreditNote (GncInvoice *invoice, gboolean credit_note)
579 GValue v = G_VALUE_INIT;
580 if (!invoice)
return;
581 gncInvoiceBeginEdit (invoice);
582 g_value_init (&v, G_TYPE_INT64);
583 g_value_set_int64 (&v, credit_note ? 1 : 0);
586 mark_invoice (invoice);
587 gncInvoiceCommitEdit (invoice);
596 void gncInvoiceSetCurrency (GncInvoice *invoice, gnc_commodity *currency)
598 if (!invoice || !currency)
return;
599 if (invoice->currency &&
602 gncInvoiceBeginEdit (invoice);
603 invoice->currency = currency;
604 mark_invoice (invoice);
605 gncInvoiceCommitEdit (invoice);
608 void gncInvoiceSetBillTo (GncInvoice *invoice,
GncOwner *billto)
610 if (!invoice || !billto)
return;
613 gncInvoiceBeginEdit (invoice);
614 gncOwnerCopy (billto, &invoice->billto);
615 mark_invoice (invoice);
616 gncInvoiceCommitEdit (invoice);
619 void gncInvoiceSetToChargeAmount (GncInvoice *invoice, gnc_numeric amount)
621 if (!invoice)
return;
623 gncInvoiceBeginEdit (invoice);
624 invoice->to_charge_amount = amount;
625 mark_invoice (invoice);
626 gncInvoiceCommitEdit (invoice);
629 void gncInvoiceSetPostedTxn (GncInvoice *invoice, Transaction *txn)
631 if (!invoice)
return;
632 g_return_if_fail (invoice->posted_txn == NULL);
634 gncInvoiceBeginEdit (invoice);
635 invoice->posted_txn = txn;
636 mark_invoice (invoice);
637 gncInvoiceCommitEdit (invoice);
640 void gncInvoiceSetPostedLot (GncInvoice *invoice, GNCLot *lot)
642 if (!invoice)
return;
643 g_return_if_fail (invoice->posted_lot == NULL);
645 gncInvoiceBeginEdit (invoice);
646 invoice->posted_lot = lot;
647 mark_invoice (invoice);
648 gncInvoiceCommitEdit (invoice);
651 void gncInvoiceSetPostedAcc (GncInvoice *invoice,
Account *acc)
653 if (!invoice)
return;
654 g_return_if_fail (invoice->posted_acc == NULL);
656 gncInvoiceBeginEdit (invoice);
657 invoice->posted_acc = acc;
658 mark_invoice (invoice);
659 gncInvoiceCommitEdit (invoice);
662 void gncInvoiceAddEntry (GncInvoice *invoice, GncEntry *entry)
668 if (!invoice || !entry)
return;
670 old = gncEntryGetInvoice (entry);
671 if (old == invoice)
return;
672 if (old) gncInvoiceRemoveEntry (old, entry);
674 gncInvoiceBeginEdit (invoice);
675 gncEntrySetInvoice (entry, invoice);
676 invoice->entries = g_list_insert_sorted (invoice->entries, entry,
677 (GCompareFunc)gncEntryCompare);
678 mark_invoice (invoice);
679 gncInvoiceCommitEdit (invoice);
682 void gncInvoiceRemoveEntry (GncInvoice *invoice, GncEntry *entry)
684 if (!invoice || !entry)
return;
686 gncInvoiceBeginEdit (invoice);
687 gncEntrySetInvoice (entry, NULL);
688 invoice->entries = g_list_remove (invoice->entries, entry);
689 mark_invoice (invoice);
690 gncInvoiceCommitEdit (invoice);
693 void gncInvoiceAddPrice (GncInvoice *invoice, GNCPrice *price)
696 gnc_commodity *commodity;
698 if (!invoice || !price)
return;
702 node = g_list_first (invoice->prices);
703 commodity = gnc_price_get_commodity (price);
706 GNCPrice *curr = (GNCPrice*)node->data;
709 node = g_list_next (node);
712 gncInvoiceBeginEdit (invoice);
714 invoice->prices = g_list_delete_link (invoice->prices, node);
715 invoice->prices = g_list_prepend (invoice->prices, price);
716 mark_invoice (invoice);
717 gncInvoiceCommitEdit (invoice);
726 if (!bill || !entry)
return;
728 old = gncEntryGetBill (entry);
729 if (old == bill)
return;
730 if (old) gncBillRemoveEntry (old, entry);
732 gncInvoiceBeginEdit (bill);
733 gncEntrySetBill (entry, bill);
734 bill->entries = g_list_insert_sorted (bill->entries, entry,
735 (GCompareFunc)gncEntryCompare);
737 gncInvoiceCommitEdit (bill);
740 void gncBillRemoveEntry (GncInvoice *bill, GncEntry *entry)
742 if (!bill || !entry)
return;
744 gncInvoiceBeginEdit (bill);
745 gncEntrySetBill (entry, NULL);
746 bill->entries = g_list_remove (bill->entries, entry);
748 gncInvoiceCommitEdit (bill);
753 if (!invoice)
return;
754 invoice->entries = g_list_sort (invoice->entries,
755 (GCompareFunc)gncEntryCompare);
756 gncInvoiceBeginEdit (invoice);
757 mark_invoice (invoice);
758 gncInvoiceCommitEdit (invoice);
763 if (!invoice)
return;
767 for (GList *next, *node = invoice->entries; node; node = next)
770 GncEntry *entry = node->data;
772 switch (gncInvoiceGetOwnerType (invoice))
774 case GNC_OWNER_VENDOR:
775 case GNC_OWNER_EMPLOYEE:
777 gncBillRemoveEntry (invoice, entry);
779 case GNC_OWNER_CUSTOMER:
782 gncInvoiceRemoveEntry (invoice, entry);
789 if (!(gncEntryGetInvoice (entry) ||
790 gncEntryGetBill (entry) ||
791 gncEntryGetOrder (entry)))
793 gncEntryBeginEdit (entry);
794 gncEntryDestroy (entry);
802 const char * gncInvoiceGetID (
const GncInvoice *invoice)
804 if (!invoice)
return NULL;
808 const GncOwner * gncInvoiceGetOwner (
const GncInvoice *invoice)
810 if (!invoice)
return NULL;
811 return &invoice->owner;
814 static QofInstance * qofInvoiceGetOwner (GncInvoice *invoice)
822 owner = &invoice->owner;
823 return QOF_INSTANCE(owner);
826 static QofInstance * qofInvoiceGetBillTo (GncInvoice *invoice)
834 billto = &invoice->billto;
835 return QOF_INSTANCE(billto);
838 time64 gncInvoiceGetDateOpened (
const GncInvoice *invoice)
840 if (!invoice)
return INT64_MAX;
841 return invoice->date_opened;
844 time64 gncInvoiceGetDatePosted (
const GncInvoice *invoice)
846 if (!invoice)
return INT64_MAX;
847 return invoice->date_posted;
850 time64 gncInvoiceGetDateDue (
const GncInvoice *invoice)
853 if (!invoice)
return INT64_MAX;
854 txn = gncInvoiceGetPostedTxn (invoice);
855 if (!txn)
return INT64_MAX;
859 GncBillTerm * gncInvoiceGetTerms (
const GncInvoice *invoice)
861 if (!invoice)
return NULL;
862 return invoice->terms;
865 const char * gncInvoiceGetBillingID (
const GncInvoice *invoice)
867 if (!invoice)
return NULL;
868 return invoice->billing_id;
871 const char * gncInvoiceGetNotes (
const GncInvoice *invoice)
873 if (!invoice)
return NULL;
874 return invoice->notes;
877 const char * gncInvoiceGetDocLink (
const GncInvoice *invoice)
879 if (!invoice)
return NULL;
881 GValue v = G_VALUE_INIT;
883 const char *rv = G_VALUE_HOLDS_STRING(&v) ? g_value_get_string (&v) : NULL;
889 GncOwnerType gncInvoiceGetOwnerType (
const GncInvoice *invoice)
892 g_return_val_if_fail (invoice, GNC_OWNER_NONE);
898 static gnc_numeric gncInvoiceSumTaxesInternal (AccountValueList *taxes)
900 gnc_numeric tt = gnc_numeric_zero ();
908 for (node = taxes; node; node=node->next)
910 GncAccountValue *acc_val = node->data;
918 static gnc_numeric gncInvoiceGetNetAndTaxesInternal (GncInvoice *invoice, gboolean use_value,
919 AccountValueList **taxes,
920 gboolean use_payment_type,
921 GncEntryPaymentType type)
924 gnc_numeric net_total = gnc_numeric_zero ();
925 gboolean is_cust_doc, is_cn;
926 AccountValueList *tv_list = NULL;
929 g_return_val_if_fail (invoice, net_total);
935 is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
936 is_cn = gncInvoiceGetIsCreditNote (invoice);
939 for (node = gncInvoiceGetEntries (invoice); node; node = node->next)
941 GncEntry *entry = node->data;
944 if (use_payment_type && gncEntryGetBillPayment (entry) != type)
951 value = gncEntryGetDocValue (entry, TRUE, is_cust_doc, is_cn);
955 PWARN (
"bad value in our entry");
971 for (node = tv_list; node; node=node->next)
973 GncAccountValue *acc_val = node->data;
980 LEAVE (
"%" PRId64
"/%" PRId64, net_total.num, net_total.denom);
984 static gnc_numeric gncInvoiceGetTotalInternal (GncInvoice *invoice, gboolean use_value,
986 gboolean use_payment_type, GncEntryPaymentType type)
988 AccountValueList *taxes;
991 if (!invoice)
return gnc_numeric_zero ();
994 total = gncInvoiceGetNetAndTaxesInternal (invoice, use_value, use_tax? &taxes : NULL, use_payment_type, type);
1005 LEAVE (
"%" PRId64
"/%" PRId64, total.num, total.denom);
1011 if (!invoice)
return gnc_numeric_zero ();
1012 return gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, FALSE, 0);
1015 gnc_numeric gncInvoiceGetTotalSubtotal (GncInvoice *invoice)
1017 if (!invoice)
return gnc_numeric_zero ();
1018 return gncInvoiceGetTotalInternal (invoice, TRUE, FALSE, FALSE, 0);
1021 gnc_numeric gncInvoiceGetTotalTax (GncInvoice *invoice)
1023 if (!invoice)
return gnc_numeric_zero ();
1024 return gncInvoiceGetTotalInternal (invoice, FALSE, TRUE, FALSE, 0);
1027 gnc_numeric gncInvoiceGetTotalOf (GncInvoice *invoice, GncEntryPaymentType type)
1029 if (!invoice)
return gnc_numeric_zero ();
1030 return gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, TRUE, type);
1035 AccountValueList *taxes;
1036 if (!invoice)
return NULL;
1038 gncInvoiceGetNetAndTaxesInternal (invoice, FALSE, &taxes, FALSE, 0);
1042 GList * gncInvoiceGetTypeListForOwnerType (GncOwnerType type)
1044 GList *type_list = NULL;
1047 case GNC_OWNER_CUSTOMER:
1048 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_CUST_INVOICE));
1049 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_CUST_CREDIT_NOTE));
1051 case GNC_OWNER_VENDOR:
1052 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_VEND_INVOICE));
1053 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_VEND_CREDIT_NOTE));
1055 case GNC_OWNER_EMPLOYEE:
1056 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_EMPL_INVOICE));
1057 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_EMPL_CREDIT_NOTE));
1060 PWARN(
"Bad owner type, no invoices.");
1066 GncInvoiceType gncInvoiceGetType (
const GncInvoice *invoice)
1068 if (!invoice)
return GNC_INVOICE_UNDEFINED;
1069 switch (gncInvoiceGetOwnerType (invoice))
1071 case GNC_OWNER_CUSTOMER:
1072 return (gncInvoiceGetIsCreditNote (invoice) ?
1073 GNC_INVOICE_CUST_CREDIT_NOTE :
1074 GNC_INVOICE_CUST_INVOICE);
1075 case GNC_OWNER_VENDOR:
1076 return (gncInvoiceGetIsCreditNote (invoice) ?
1077 GNC_INVOICE_VEND_CREDIT_NOTE :
1078 GNC_INVOICE_VEND_INVOICE);
1079 case GNC_OWNER_EMPLOYEE:
1080 return (gncInvoiceGetIsCreditNote (invoice) ?
1081 GNC_INVOICE_EMPL_CREDIT_NOTE :
1082 GNC_INVOICE_EMPL_INVOICE);
1084 PWARN (
"No invoice types defined for owner %d",
1085 gncInvoiceGetOwnerType (invoice));
1086 return GNC_INVOICE_UNDEFINED;
1090 const char * gncInvoiceGetTypeString (
const GncInvoice *invoice)
1092 GncInvoiceType type = gncInvoiceGetType (invoice);
1095 case GNC_INVOICE_CUST_INVOICE:
1096 return _(
"Invoice");
1097 case GNC_INVOICE_VEND_INVOICE:
1099 case GNC_INVOICE_EMPL_INVOICE:
1100 return _(
"Expense");
1101 case GNC_INVOICE_CUST_CREDIT_NOTE:
1102 case GNC_INVOICE_VEND_CREDIT_NOTE:
1103 case GNC_INVOICE_EMPL_CREDIT_NOTE:
1104 return _(
"Credit Note");
1106 PWARN(
"Unknown invoice type");
1111 gnc_commodity * gncInvoiceGetCurrency (
const GncInvoice *invoice)
1113 if (!invoice)
return NULL;
1114 return invoice->currency;
1117 GncOwner * gncInvoiceGetBillTo (GncInvoice *invoice)
1119 if (!invoice)
return NULL;
1120 return &invoice->billto;
1123 GNCLot * gncInvoiceGetPostedLot (
const GncInvoice *invoice)
1125 if (!invoice)
return NULL;
1126 return invoice->posted_lot;
1129 Transaction * gncInvoiceGetPostedTxn (
const GncInvoice *invoice)
1131 if (!invoice)
return NULL;
1132 return invoice->posted_txn;
1135 Account * gncInvoiceGetPostedAcc (
const GncInvoice *invoice)
1137 if (!invoice)
return NULL;
1138 return invoice->posted_acc;
1141 gboolean gncInvoiceGetActive (
const GncInvoice *invoice)
1143 if (!invoice)
return FALSE;
1144 return invoice->active;
1147 gboolean gncInvoiceGetIsCreditNote (
const GncInvoice *invoice)
1149 GValue v = G_VALUE_INIT;
1151 if (!invoice)
return FALSE;
1153 retval = G_VALUE_HOLDS_INT64(&v) && g_value_get_int64 (&v);
1159 gnc_numeric gncInvoiceGetToChargeAmount (
const GncInvoice *invoice)
1161 if (!invoice)
return gnc_numeric_zero ();
1162 return invoice->to_charge_amount;
1165 EntryList * gncInvoiceGetEntries (GncInvoice *invoice)
1167 if (!invoice)
return NULL;
1168 return invoice->entries;
1171 GNCPrice * gncInvoiceGetPrice (GncInvoice *invoice, gnc_commodity *commodity)
1173 GList *node = g_list_first (invoice->prices);
1175 while (node != NULL)
1177 GNCPrice *curr = (GNCPrice*)node->data;
1182 node = g_list_next (node);
1188 static QofCollection*
1189 qofInvoiceGetEntries (GncInvoice *invoice)
1191 QofCollection *entry_coll;
1196 for (list = gncInvoiceGetEntries (invoice); list != NULL; list = list->next)
1198 entry = QOF_INSTANCE(list->data);
1205 qofInvoiceEntryCB (
QofInstance *ent, gpointer user_data)
1207 GncInvoice *invoice;
1209 invoice = (GncInvoice*)user_data;
1210 if (!invoice || !ent)
1214 switch (gncInvoiceGetOwnerType (invoice))
1216 case GNC_OWNER_VENDOR:
1223 gncInvoiceAddEntry (invoice, (GncEntry*)ent);
1230 qofInvoiceSetEntries (GncInvoice *invoice, QofCollection *entry_coll)
1238 qof_collection_foreach (entry_coll, qofInvoiceEntryCB, invoice);
1243 qofInvoiceGetJob (
const GncInvoice *invoice)
1249 return invoice->job;
1253 qofInvoiceSetJob (GncInvoice *invoice, GncJob *job)
1263 gncInvoiceDetachFromLot (GNCLot *lot)
1267 gnc_lot_begin_edit (lot);
1269 gnc_lot_commit_edit (lot);
1270 gnc_lot_set_cached_invoice (lot, NULL);
1274 gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot)
1277 if (!invoice || !lot)
1280 if (invoice->posted_lot)
return;
1282 gnc_lot_begin_edit (lot);
1284 gnc_lot_commit_edit (lot);
1285 gnc_lot_set_cached_invoice (lot, invoice);
1286 gncInvoiceSetPostedLot (invoice, lot);
1293 GncInvoice *invoice = NULL;
1295 if (!lot)
return NULL;
1300 book = gnc_lot_get_book (lot);
1302 invoice = gncInvoiceLookup (book, guid);
1304 gnc_lot_set_cached_invoice (lot, invoice);
1311 gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
1313 if (!invoice || !txn)
1316 if (invoice->posted_txn)
return;
1323 gncInvoiceSetPostedTxn (invoice, txn);
1331 GncInvoice *invoice = NULL;
1333 if (!txn)
return NULL;
1337 invoice = gncInvoiceLookup (book, guid);
1344 switch (gncInvoiceGetType (invoice))
1346 case GNC_INVOICE_CUST_INVOICE:
1347 case GNC_INVOICE_VEND_CREDIT_NOTE:
1348 case GNC_INVOICE_EMPL_CREDIT_NOTE:
1350 case GNC_INVOICE_CUST_CREDIT_NOTE:
1351 case GNC_INVOICE_VEND_INVOICE:
1352 case GNC_INVOICE_EMPL_INVOICE:
1354 case GNC_INVOICE_UNDEFINED:
1358 g_assert_not_reached ();
1365 EntryList *entries_iter;
1366 gboolean is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
1367 gboolean is_cn = gncInvoiceGetIsCreditNote (invoice);
1368 GHashTable *amt_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal,
1372 for (entries_iter = invoice->entries; entries_iter != NULL; entries_iter = g_list_next(entries_iter))
1374 GncEntry *entry = (GncEntry*)entries_iter->data;
1376 gnc_commodity *account_currency;
1377 AccountValueList *tt_amts = NULL, *tt_iter;
1380 this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
1381 gncEntryGetBillAccount (entry));
1387 gnc_numeric *curr_amt = (gnc_numeric*) g_hash_table_lookup (amt_hash, account_currency);
1388 gnc_numeric *entry_amt = (gnc_numeric*) g_new0 (gnc_numeric, 1);
1389 *entry_amt = gncEntryGetDocValue (entry, FALSE, is_cust_doc, is_cn);
1392 g_hash_table_insert (amt_hash, account_currency, entry_amt);
1402 for (tt_iter = tt_amts; tt_iter != NULL; tt_iter = g_list_next(tt_iter))
1404 GncAccountValue *tt_amt_val = (GncAccountValue*)tt_iter->data;
1405 Account *tt_acc = tt_amt_val->account;
1411 gnc_numeric *curr_amt = (gnc_numeric*) g_hash_table_lookup (amt_hash, tt_acc_currency);
1412 gnc_numeric *tt_acc_amt = (gnc_numeric*) g_new0 (gnc_numeric, 1);
1413 *tt_acc_amt = tt_amt_val->value;
1416 g_hash_table_insert (amt_hash, tt_acc_currency, tt_acc_amt);
1426 static gboolean gncInvoicePostAddSplit (QofBook *book,
1432 GncInvoice *invoice)
1442 gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
1479 PERR(
"Multiple commodities with no price.");
1485 gnc_numeric converted_amount;
1499 const char * memo, gboolean accumulatesplits,
1506 GList *splitinfo = NULL;
1508 gboolean is_cust_doc;
1510 const char *name, *type;
1515 AccountValueList *taxes;
1517 if (!invoice || !acc)
return NULL;
1518 if (gncInvoiceIsPosted (invoice))
return NULL;
1521 gncInvoiceBeginEdit (invoice);
1526 gncInvoiceSetTerms (invoice,
1527 gncBillTermReturnChild (invoice->terms, TRUE));
1530 is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
1531 is_cn = gncInvoiceGetIsCreditNote (invoice);
1535 if (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_EMPLOYEE)
1539 lot = gnc_lot_new (book);
1540 gncInvoiceAttachToLot (invoice, lot);
1541 gnc_lot_begin_edit (lot);
1543 type = gncInvoiceGetTypeString (invoice);
1546 lot_title = g_strdup_printf (
"%s %s", type, gncInvoiceGetID (invoice));
1547 gnc_lot_set_title (lot, lot_title);
1559 gnc_set_num_action (txn, NULL, gncInvoiceGetID (invoice), type);
1577 if (is_cust_doc != is_cn)
1581 for (node = taxes; node; node = node->next)
1583 GncAccountValue *acc_val = node->data;
1592 for (iter = gncInvoiceGetEntries (invoice); iter; iter = iter->next)
1594 gnc_numeric value, tax;
1595 GncEntry * entry = iter->data;
1599 gncEntryBeginEdit (entry);
1601 gncEntrySetInvTaxTable
1602 (entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE));
1605 gncEntrySetBillTaxTable
1606 (entry, gncTaxTableReturnChild (gncEntryGetBillTaxTable (entry), TRUE));
1609 if (gncEntryGetBillable (entry))
1612 gncEntrySetInvPrice (entry, gncEntryGetPrice (entry, FALSE, TRUE));
1613 gncEntrySetInvTaxIncluded (entry, FALSE);
1616 gncEntryCommitEdit (entry);
1620 value = gncEntryGetBalValue (entry, TRUE, is_cust_doc);
1621 tax = gncEntryGetBalTaxValue (entry, TRUE, is_cust_doc);
1623 DEBUG (
"Tax %" PRId64
"/%" PRId64
" on entry value %" PRId64
"/%" PRId64,
1624 tax.num, tax.denom, value.num, value.denom);
1626 this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
1627 gncEntryGetBillAccount (entry));
1632 if (accumulatesplits)
1635 else if (!gncInvoicePostAddSplit (book, this_acc, txn, value,
1636 gncEntryGetDescription (entry),
1643 PERR(
"Failed to add split %s", gncEntryGetDescription (entry));
1657 if (ccard_acct && gncEntryGetBillPayment (entry) == GNC_PAYMENT_CARD)
1667 gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
1679 PWARN (
"bad value in our entry");
1684 PWARN (
"bad tax in our entry");
1695 PINFO (
"Processing Split List");
1696 for (iter = splitinfo; iter; iter = iter->next)
1698 GncAccountValue *acc_val = iter->data;
1702 if (!gncInvoicePostAddSplit (book, acc_val->account, txn, acc_val->value,
1703 memo, type, invoice))
1709 PERR(
"Failed to add split %s, aborting accumulated splits.", memo);
1723 gnc_numeric to_charge_bal_amount = (is_cn ?
gnc_numeric_neg (invoice->to_charge_amount)
1724 : invoice->to_charge_amount);
1726 PINFO (
"Process to_card payment split");
1730 gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
1747 PINFO (
"Process to_card balancing split");
1751 gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
1765 gncInvoiceAttachToTxn (invoice, txn);
1766 gncInvoiceSetPostedAcc (invoice, acc);
1773 gnc_lot_commit_edit (lot);
1776 DEBUG(
"Committing Invoice %s", invoice->id);
1777 mark_invoice (invoice);
1778 gncInvoiceCommitEdit (invoice);
1795 GList *lot_split_list, *lot_split_iter;
1797 if (!invoice)
return FALSE;
1798 if (!gncInvoiceIsPosted (invoice))
return FALSE;
1800 txn = gncInvoiceGetPostedTxn (invoice);
1801 g_return_val_if_fail (txn, FALSE);
1803 lot = gncInvoiceGetPostedLot (invoice);
1804 g_return_val_if_fail (lot, FALSE);
1808 xaccTransClearReadOnly (txn);
1814 gncInvoiceDetachFromLot (lot);
1833 PINFO (
"Recreating link transactions for remaining lots");
1834 for (lot_split_iter = lot_split_list; lot_split_iter; lot_split_iter = lot_split_iter->next)
1836 Split *split = lot_split_iter->data;
1837 GList *other_split_list, *list_iter;
1839 GList *lot_list = NULL;
1848 for (list_iter = other_split_list; list_iter; list_iter = list_iter->next)
1850 Split *other_split = list_iter->data;
1854 if (other_lot == lot)
1857 lot_list = g_list_prepend (lot_list, other_lot);
1860 lot_list = g_list_reverse (lot_list);
1863 xaccTransClearReadOnly (other_txn);
1874 for (list_iter = lot_list; list_iter; list_iter = list_iter->next)
1876 GNCLot *other_lot = list_iter->data;
1879 if (!gnc_lot_count_splits (other_lot))
1880 gnc_lot_destroy (other_lot);
1881 else if (other_invoice)
1882 qof_event_gen (QOF_INSTANCE(other_invoice), QOF_EVENT_MODIFY, NULL);
1884 g_list_free (lot_list);
1886 g_list_free (lot_split_list);
1889 if (!gnc_lot_count_splits (lot))
1890 gnc_lot_destroy (lot);
1893 gncInvoiceBeginEdit (invoice);
1895 invoice->posted_acc = NULL;
1896 invoice->posted_txn = NULL;
1897 invoice->posted_lot = NULL;
1898 invoice->date_posted = INT64_MAX;
1901 if (reset_tax_tables)
1903 gboolean is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
1906 for (iter = gncInvoiceGetEntries (invoice); iter; iter = iter->next)
1908 GncEntry *entry = iter->data;
1910 gncEntryBeginEdit (entry);
1912 gncEntrySetInvTaxTable (entry,
1913 gncTaxTableGetParent (gncEntryGetInvTaxTable( entry)));
1915 gncEntrySetBillTaxTable (entry,
1916 gncTaxTableGetParent (gncEntryGetBillTaxTable (entry)));
1917 gncEntryCommitEdit (entry);
1921 mark_invoice (invoice);
1922 gncInvoiceCommitEdit (invoice);
1932 gboolean positive_balance;
1936 gnc_lot_match_owner_balancing (GNCLot *lot, gpointer user_data)
1978 g_return_if_fail (invoice);
1979 g_return_if_fail (invoice->posted_lot);
1981 inv_lot = invoice->posted_lot;
1982 acct = invoice->posted_acc;
1996 lot_list = g_list_prepend (lot_list, inv_lot);
1998 g_list_free (lot_list);
2007 Account *xfer_acc, gnc_numeric amount,
2008 gnc_numeric exch,
time64 date,
2009 const char *memo,
const char *num)
2011 GNCLot *payment_lot;
2012 GList *selected_lots = NULL;
2016 if (!invoice || !gncInvoiceIsPosted (invoice) || !xfer_acc)
return;
2019 g_return_if_fail (owner->owner.undefined);
2023 invoice->posted_acc,
2024 xfer_acc, amount, exch,
2028 selected_lots = g_list_prepend (selected_lots, invoice->posted_lot);
2032 selected_lots = g_list_prepend (selected_lots, payment_lot);
2036 gboolean gncInvoiceIsPosted (
const GncInvoice *invoice)
2038 if (!invoice)
return FALSE;
2039 return GNC_IS_TRANSACTION(gncInvoiceGetPostedTxn (invoice));
2042 gboolean gncInvoiceIsPaid (
const GncInvoice *invoice)
2044 if (!invoice)
return FALSE;
2045 if (!invoice->posted_lot)
return FALSE;
2051 void gncInvoiceBeginEdit (GncInvoice *invoice)
2058 PERR(
"Invoice QofBackend Failure: %d", errcode);
2059 gnc_engine_signal_commit_error (errcode);
2062 static void gncInvoiceOnDone (
QofInstance *invoice) { }
2066 GncInvoice *invoice = (GncInvoice *) inst;
2067 gncInvoiceFree (invoice);
2070 void gncInvoiceCommitEdit (GncInvoice *invoice)
2074 gncInvoiceOnDone, invoice_free);
2077 int gncInvoiceCompare (
const GncInvoice *a,
const GncInvoice *b)
2081 if (a == b)
return 0;
2085 compare = g_strcmp0 (a->id, b->id);
2086 if (compare)
return compare;
2087 if (a->date_opened != b->date_opened)
return a->date_opened - b->date_opened;
2088 if (a->date_posted != b->date_posted)
return a->date_posted - b->date_posted;
2094 if (a == NULL && b == NULL)
return TRUE;
2095 if (a == NULL || b == NULL)
return FALSE;
2097 g_return_val_if_fail (GNC_IS_INVOICE(a), FALSE);
2098 g_return_val_if_fail (GNC_IS_INVOICE(b), FALSE);
2100 if (g_strcmp0 (a->id, b->id) != 0)
2102 PWARN(
"IDs differ: %s vs %s", a->id, b->id);
2106 if (g_strcmp0 (a->notes, b->notes) != 0)
2108 PWARN(
"Notes differ: %s vs %s", a->notes, b->notes);
2112 if (g_strcmp0 (a->billing_id, b->billing_id) != 0)
2114 PWARN(
"Billing IDs differ: %s vs %s", a->billing_id, b->billing_id);
2118 if (g_strcmp0 (a->printname, b->printname) != 0)
2120 PWARN(
"Printnames differ: %s vs %s", a->printname, b->printname);
2124 if (a->active != b->active)
2126 PWARN(
"Active flags differ");
2132 PWARN(
"Billterms differ");
2136 if (!gncJobEqual (a->job, b->job))
2138 PWARN(
"Jobs differ");
2144 PWARN(
"Currencies differ");
2150 PWARN(
"Posted accounts differ");
2154 if (!
xaccTransEqual (a->posted_txn, b->posted_txn, TRUE, TRUE, TRUE, FALSE))
2156 PWARN(
"Posted tx differ");
2161 if (!gncLotEqual (a->posted_lot, b->posted_lot))
2163 PWARN(
"Posted lots differ");
2177 gnc_numeric to_charge_amount;
2186 static const char * _gncInvoicePrintable (gpointer obj)
2188 GncInvoice *invoice = obj;
2190 g_return_val_if_fail (invoice, NULL);
2194 if (invoice->printname) g_free (invoice->printname);
2196 invoice->printname =
2197 g_strdup_printf (
"%s%s", invoice->id,
2198 gncInvoiceIsPosted (invoice) ? _(
" (posted)") :
"");
2201 return invoice->printname;
2205 destroy_invoice_on_book_close (
QofInstance *ent, gpointer data)
2207 GncInvoice* invoice = GNC_INVOICE(ent);
2209 gncInvoiceBeginEdit (invoice);
2210 gncInvoiceDestroy (invoice);
2214 gnc_invoice_book_end (QofBook* book)
2219 qof_collection_foreach (col, destroy_invoice_on_book_close, NULL);
2222 static QofObject gncInvoiceDesc =
2225 DI(.e_type = ) _GNC_MOD_NAME,
2226 DI(.type_label = ) "Invoice",
2227 DI(.create = ) (gpointer)gncInvoiceCreate,
2228 DI(.book_begin = ) NULL,
2229 DI(.book_end = ) gnc_invoice_book_end,
2232 DI(.foreach = ) qof_collection_foreach,
2233 DI(.printable = ) _gncInvoicePrintable,
2240 static QofParam params[] =
2243 INVOICE_FROM_LOT, _GNC_MOD_NAME,
2255 static QofParam params[] =
2258 INVOICE_FROM_TXN, _GNC_MOD_NAME,
2267 gboolean gncInvoiceRegister (
void)
2269 static QofParam params[] =
2272 { INVOICE_OWNER, GNC_ID_OWNER, (
QofAccessFunc)gncInvoiceGetOwner, NULL },
2274 { INVOICE_DUE, QOF_TYPE_DATE, (
QofAccessFunc)gncInvoiceGetDateDue, NULL },
2276 { INVOICE_IS_POSTED, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncInvoiceIsPosted, NULL },
2277 { INVOICE_IS_PAID, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncInvoiceIsPaid, NULL },
2283 { INVOICE_POST_LOT, GNC_ID_LOT, (
QofAccessFunc)gncInvoiceGetPostedLot, NULL },
2284 { INVOICE_TYPE, QOF_TYPE_INT32, (
QofAccessFunc)gncInvoiceGetType, NULL },
2285 { INVOICE_TYPE_STRING, QOF_TYPE_STRING, (
QofAccessFunc)gncInvoiceGetTypeString, NULL },
2287 { INVOICE_BILLTO, GNC_ID_OWNER, (
QofAccessFunc)gncInvoiceGetBillTo, NULL },
2304 qofInvoiceSetEntries (NULL, NULL);
2305 qofInvoiceGetEntries (NULL);
2306 qofInvoiceSetOwner (NULL, NULL);
2307 qofInvoiceGetOwner (NULL);
2308 qofInvoiceSetBillTo (NULL, NULL);
2309 qofInvoiceGetBillTo (NULL);
2314 gchar *gncInvoiceNextID (QofBook *book,
const GncOwner *owner)
2319 case GNC_OWNER_CUSTOMER:
2322 case GNC_OWNER_VENDOR:
2325 case GNC_OWNER_EMPLOYEE:
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
void xaccSplitSetBaseValue(Split *s, gnc_numeric value, const gnc_commodity *base_currency)
Depending on the base_currency, set either the value or the amount of this split or both: If the base...
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
#define QOF_TYPE_COLLECT
secondary collections are used for one-to-many references between entities and are implemented using ...
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
void qof_instance_set_kvp(QofInstance *, GValue const *value, unsigned count,...)
Sets a KVP slot to a value from a GValue.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of 'dirty' flag on collection.
char xaccTransGetTxnType(Transaction *trans)
Returns the Transaction Type: note this type will be derived from the transaction splits...
#define TXN_TYPE_INVOICE
Transaction is an invoice.
#define PINFO(format, args...)
Print an informational note.
GncInvoice * gnc_lot_get_cached_invoice(const GNCLot *lot)
Returns the invoice with which this lot is associated.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
gchar * qof_book_increment_and_format_counter(QofBook *book, const char *counter_name)
This will increment the named counter for this book and format it.
GList * qof_instance_get_referring_object_list_from_collection(const QofCollection *coll, const QofInstance *ref)
Returns a list of objects from the collection which refer to the specific object. ...
#define DEBUG(format, args...)
Print a debugging message.
void qof_instance_set(QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_set Group setting multiple parameters in a single begin/commit/rollback.
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
AccountValueList * gncEntryGetDocTaxValues(GncEntry *entry, gboolean is_cust_doc, gboolean is_cn)
Careful: the returned list is NOT owned by the entry and should be freed by the caller.
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
This function registers a new object class with the Qof subsystem.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
void gnc_lot_add_split(GNCLot *lot, Split *split)
Adds a split to this lot.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gboolean gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
void gncInvoiceRemoveEntries(GncInvoice *invoice)
Remove all entries from an invoice.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
Transaction * gncInvoicePostToAccount(GncInvoice *invoice, Account *acc, time64 post_date, time64 due_date, const char *memo, gboolean accumulatesplits, gboolean autopay)
Post this invoice to an account.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
QofCollection * qof_instance_get_collection(gconstpointer ptr)
Return the collection this instance belongs to.
Use any denominator which gives an exactly correct ratio of numerator to denominator.
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type.
GHashTable * gncInvoiceGetForeignCurrencies(const GncInvoice *invoice)
Return an overview of amounts on this invoice that will be posted to accounts in currencies that are ...
void gncInvoiceSortEntries(GncInvoice *invoice)
Call this function when an Entry is changed and you want to re-sort the list of entries.
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
gnc_numeric gncInvoiceGetTotal(GncInvoice *invoice)
Return the "total" amount of the invoice as seen on the document (and shown to the user in the report...
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue.
gboolean gncBillTermEqual(const GncBillTerm *a, const GncBillTerm *b)
Check if all internal fields of a and b match.
QofInstance * qofOwnerGetOwner(const GncOwner *owner)
return the owner itself as an entity.
void gncInvoiceAutoApplyPayments(GncInvoice *invoice)
Attempt to pay the invoice using open payment lots and lots for documents of the opposite sign (credi...
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
void gncOwnerAutoApplyPaymentsWithLots(const GncOwner *owner, GList *lots)
Given a list of lots, try to balance as many of them as possible by creating balancing transactions b...
GncInvoice * gncInvoiceGetInvoiceFromTxn(const Transaction *txn)
Given a transaction, find and return the Invoice.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
#define PWARN(format, args...)
Log a warning.
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
void xaccTransSetTxnType(Transaction *trans, char type)
Set the Transaction Type: note the type will be saved into the Transaction kvp property as a backward...
double gnc_numeric_to_double(gnc_numeric in)
Convert numeric to floating-point value.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
gboolean xaccTransEqual(const Transaction *ta, const Transaction *tb, gboolean check_guids, gboolean check_splits, gboolean check_balances, gboolean assume_ordered)
Equality.
Account handling public routines.
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Change the denominator of a gnc_numeric value to the specified denominator under standard arguments '...
Find the least common multiple of the arguments' denominators and use that as the denominator of the ...
void xaccTransSetReadOnly(Transaction *trans, const char *reason)
Set the transaction to be ReadOnly by setting a non-NULL value as "reason".
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object has been modified.
SplitList * gnc_lot_get_split_list(const GNCLot *lot)
Returns a list of all the splits in this lot.
void gncBillAddEntry(GncInvoice *bill, GncEntry *entry)
Call this function when adding an entry to a bill instead of an invoice.
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction.
void qofOwnerSetEntity(GncOwner *owner, QofInstance *ent)
set the owner from the entity.
void gncInvoiceApplyPayment(const GncInvoice *invoice, Transaction *txn, Account *xfer_acc, gnc_numeric amount, gnc_numeric exch, time64 date, const char *memo, const char *num)
A convenience function to apply a payment to an invoice.
void gncOwnerAttachToLot(const GncOwner *owner, GNCLot *lot)
Attach an owner to a lot.
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
part2 – deal with the backend
gboolean gncOwnerGetOwnerFromLot(GNCLot *lot, GncOwner *owner)
Get the owner from the lot.
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
#define xaccTransGetBook(X)
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
void xaccTransSetDateDue(Transaction *trans, time64 time)
Dates and txn-type for A/R and A/P "invoice" postings.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
void gncAccountValueDestroy(GList *list)
Destroy a list of accountvalues.
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare.
#define TXN_TYPE_LINK
Transaction is a link between (invoice and payment) lots.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
GNCLot * gncOwnerCreatePaymentLotSecs(const GncOwner *owner, Transaction **preset_txn, Account *posted_acc, Account *xfer_acc, gnc_numeric amount, gnc_numeric exch, time64 date, const char *memo, const char *num)
Create a lot for a payment to the owner using the other parameters passed in.
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
Split * xaccMallocSplit(QofBook *book)
Constructor.
void gncInvoiceSetDateOpenedGDate(GncInvoice *invoice, const GDate *date)
Set the DateOpened using a GDate argument.
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b.
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
const GncOwner * gncOwnerGetEndOwner(const GncOwner *owner)
Get the "parent" Owner or GncGUID thereof.
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Business Invoice Interface.
QofIdType qof_collection_get_type(const QofCollection *col)
return the type that the collection stores
gboolean gncInvoiceUnpost(GncInvoice *invoice, gboolean reset_tax_tables)
Unpost this invoice.
gboolean qof_collection_add_entity(QofCollection *coll, QofInstance *ent)
Add an entity to a QOF_TYPE_COLLECT.
gboolean gnc_lot_is_closed(GNCLot *lot)
Returns closed status of the given lot.
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
GList * gncAccountValueAddList(GList *l1, GList *l2)
Merge l2 into l1.
#define LEAVE(format, args...)
Print a function exit debugging message.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
time64 gnc_time(time64 *tbuf)
get the current time
GNCNumericErrorCode gnc_numeric_check(gnc_numeric in)
Check for error signal in value.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
GList * gncAccountValueAdd(GList *list, Account *acc, gnc_numeric value)
This will add value to the account-value for acc, creating a new list object if necessary.
LotList * xaccAccountFindOpenLots(const Account *acc, gboolean(*match_func)(GNCLot *lot, gpointer user_data), gpointer user_data, GCompareFunc sort_func)
Find a list of open lots that match the match_func.
Business Entry Interface.
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
gboolean gncInvoiceEqual(const GncInvoice *a, const GncInvoice *b)
Test support function used by test-dbi-business-stuff.c.
time64 time64CanonicalDayTime(time64 t)
convert a time64 on a certain day (localtime) to the time64 representing midday on that day...
gboolean qof_book_shutting_down(const QofBook *book)
Is the book shutting down?
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
GncEmployee * gncOwnerGetEmployee(const GncOwner *owner)
If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object...
AccountValueList * gncInvoiceGetTotalTaxList(GncInvoice *invoice)
Return a list of tax totals accumulated per tax account.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
API for Transactions and Splits (journal entries)
The type used to store guids in C.
GncInvoice * gncInvoiceCopy(const GncInvoice *from)
Create a new GncInvoice object as a deep copy of the given other invoice.
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
time64 xaccTransRetDateDue(const Transaction *trans)
Dates and txn-type for A/R and A/P "invoice" postings.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
gboolean gncInvoiceAmountPositive(const GncInvoice *invoice)
Depending on the invoice type, invoices have a different effect on the balance.
gnc_numeric gnc_lot_get_balance(GNCLot *lot)
Returns the lot balance.
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn't be...
QofCollection * qof_collection_new(QofIdType type)
create a new collection of entities of type
gchar * qof_instance_get_display_name(const QofInstance *inst)
Returns a displayable name for this object.
Utility functions for file access.