GnuCash c935c2f+
Loading...
Searching...
No Matches
Files | Macros | Typedefs | Enumerations | Functions

An invoice holds a list of entries, a pointer to the customer, and the job, the dates entered and posted, as well as the account, transaction and lot for the posted invoice. More...

Files

file  gncInvoice.h
 Business Invoice Interface.
 

Macros

#define GNC_ID_INVOICE   "gncInvoice"
 
#define GNC_TYPE_INVOICE   (gnc_invoice_get_type ())
 
#define GNC_INVOICE(o)    (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_INVOICE, GncInvoice))
 
#define GNC_INVOICE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_INVOICE, GncInvoiceClass))
 
#define GNC_IS_INVOICE(o)    (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_INVOICE))
 
#define GNC_IS_INVOICE_CLASS(k)    (G_TYPE_CHECK_CLASS_TYPE ((k), GNC_TYPE_INVOICE))
 
#define GNC_INVOICE_GET_CLASS(o)    (G_TYPE_INSTANCE_GET_CLASS ((o), GNC_TYPE_INVOICE, GncInvoiceClass))
 
#define INVOICE_ID   "id"
 
#define INVOICE_OWNER   "owner"
 
#define INVOICE_OPENED   "date_opened"
 
#define INVOICE_POSTED   "date_posted"
 
#define INVOICE_DUE   "date_due"
 
#define INVOICE_IS_POSTED   "is_posted?"
 
#define INVOICE_IS_PAID   "is_paid?"
 
#define INVOICE_TERMS   "terms"
 
#define INVOICE_BILLINGID   "billing_id"
 
#define INVOICE_NOTES   "notes"
 
#define INVOICE_DOCLINK   "doclink"
 
#define INVOICE_ACC   "account"
 
#define INVOICE_POST_TXN   "posted_txn"
 
#define INVOICE_POST_LOT   "posted_lot"
 
#define INVOICE_IS_CN   "credit_note"
 
#define INVOICE_TYPE   "type"
 
#define INVOICE_TYPE_STRING   "type_string"
 
#define INVOICE_BILLTO   "bill-to"
 
#define INVOICE_JOB   "invoice_job"
 
#define INVOICE_FROM_LOT   "invoice-from-lot"
 
#define INVOICE_FROM_TXN   "invoice-from-txn"
 
#define gncInvoiceGetGUID(x)   qof_instance_get_guid (QOF_INSTANCE(x))
 deprecated functions
 
#define gncInvoiceRetGUID(x)   (x ? *(qof_instance_get_guid (QOF_INSTANCE(x))) : *(guid_null()))
 

Typedefs

typedef GList GncInvoiceList
 
typedef GList EntryList
 

Enumerations

enum  GncInvoiceType {
  GNC_INVOICE_UNDEFINED , GNC_INVOICE_CUST_INVOICE , GNC_INVOICE_VEND_INVOICE , GNC_INVOICE_EMPL_INVOICE ,
  GNC_INVOICE_CUST_CREDIT_NOTE , GNC_INVOICE_VEND_CREDIT_NOTE , GNC_INVOICE_EMPL_CREDIT_NOTE , GNC_INVOICE_NUM_TYPES
}
 

Functions

GType gnc_invoice_get_type (void)
 
void gncInvoiceAddEntry (GncInvoice *invoice, GncEntry *entry)
 
void gncInvoiceRemoveEntry (GncInvoice *invoice, GncEntry *entry)
 
void gncInvoiceAddPrice (GncInvoice *invoice, GNCPrice *price)
 
void gncBillAddEntry (GncInvoice *bill, GncEntry *entry)
 Call this function when adding an entry to a bill instead of an invoice.
 
void gncBillRemoveEntry (GncInvoice *bill, GncEntry *entry)
 
void gncInvoiceSortEntries (GncInvoice *invoice)
 Call this function when an Entry is changed and you want to re-sort the list of entries.
 
void gncInvoiceRemoveEntries (GncInvoice *invoice)
 Remove all entries from an invoice.
 
gnc_numeric gncInvoiceGetTotal (GncInvoice *invoice)
 Return the "total" amount of the invoice as seen on the document (and shown to the user in the reports and invoice ledger).
 
gnc_numeric gncInvoiceGetTotalOf (GncInvoice *invoice, GncEntryPaymentType type)
 
gnc_numeric gncInvoiceGetTotalSubtotal (GncInvoice *invoice)
 
gnc_numeric gncInvoiceGetTotalTax (GncInvoice *invoice)
 
AccountValueList * gncInvoiceGetTotalTaxList (GncInvoice *invoice)
 Return a list of tax totals accumulated per tax account.
 
EntryList * gncInvoiceGetEntries (GncInvoice *invoice)
 
GNCPrice * gncInvoiceGetPrice (GncInvoice *invoice, gnc_commodity *commodity)
 
gboolean gncInvoiceAmountPositive (const GncInvoice *invoice)
 Depending on the invoice type, invoices have a different effect on the balance.
 
GHashTable * gncInvoiceGetForeignCurrencies (const GncInvoice *invoice)
 Return an overview of amounts on this invoice that will be posted to accounts in currencies that are different from the invoice currency.
 
Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc, time64 posted_date, time64 due_date, const char *memo, gboolean accumulatesplits, gboolean autopay)
 Post this invoice to an account.
 
gboolean gncInvoiceUnpost (GncInvoice *invoice, gboolean reset_tax_tables)
 Unpost this invoice.
 
void gncInvoiceAutoApplyPayments (GncInvoice *invoice)
 Attempt to pay the invoice using open payment lots and lots for documents of the opposite sign (credit notes versus invoices).
 
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.
 
GncInvoice * gncInvoiceGetInvoiceFromTxn (const Transaction *txn)
 Given a transaction, find and return the Invoice.
 
GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot)
 Given a LOT, find and return the Invoice attached to the lot.
 
void gncInvoiceBeginEdit (GncInvoice *invoice)
 
void gncInvoiceCommitEdit (GncInvoice *invoice)
 
int gncInvoiceCompare (const GncInvoice *a, const GncInvoice *b)
 
gboolean gncInvoiceIsPosted (const GncInvoice *invoice)
 
gboolean gncInvoiceIsPaid (const GncInvoice *invoice)
 
QofBookgncInvoiceGetBook (GncInvoice *x)
 
gboolean gncInvoiceEqual (const GncInvoice *a, const GncInvoice *b)
 Test support function used by test-dbi-business-stuff.c.
 

Create/Destroy Functions

GncInvoice * gncInvoiceCreate (QofBook *book)
 
void gncInvoiceDestroy (GncInvoice *invoice)
 
GncInvoice * gncInvoiceCopy (const GncInvoice *other_invoice)
 Create a new GncInvoice object as a deep copy of the given other invoice.
 

Set Functions

void gncInvoiceSetID (GncInvoice *invoice, const char *id)
 
void gncInvoiceSetOwner (GncInvoice *invoice, GncOwner *owner)
 
void gncInvoiceSetDateOpenedGDate (GncInvoice *invoice, const GDate *date)
 Set the DateOpened using a GDate argument.
 
void gncInvoiceSetDateOpened (GncInvoice *invoice, time64 date)
 
void gncInvoiceSetDatePosted (GncInvoice *invoice, time64 date)
 
void gncInvoiceSetTerms (GncInvoice *invoice, GncBillTerm *terms)
 
void gncInvoiceSetBillingID (GncInvoice *invoice, const char *billing_id)
 
void gncInvoiceSetNotes (GncInvoice *invoice, const char *notes)
 
void gncInvoiceSetDocLink (GncInvoice *invoice, const char *doclink)
 
void gncInvoiceSetCurrency (GncInvoice *invoice, gnc_commodity *currency)
 
void gncInvoiceSetActive (GncInvoice *invoice, gboolean active)
 
void gncInvoiceSetIsCreditNote (GncInvoice *invoice, gboolean credit_note)
 
void gncInvoiceSetBillTo (GncInvoice *invoice, GncOwner *billto)
 
void gncInvoiceSetToChargeAmount (GncInvoice *invoice, gnc_numeric amount)
 

Get Functions

const char * gncInvoiceGetID (const GncInvoice *invoice)
 
const GncOwnergncInvoiceGetOwner (const GncInvoice *invoice)
 
time64 gncInvoiceGetDateOpened (const GncInvoice *invoice)
 
time64 gncInvoiceGetDatePosted (const GncInvoice *invoice)
 
time64 gncInvoiceGetDateDue (const GncInvoice *invoice)
 
GncBillTerm * gncInvoiceGetTerms (const GncInvoice *invoice)
 
const char * gncInvoiceGetBillingID (const GncInvoice *invoice)
 
const char * gncInvoiceGetNotes (const GncInvoice *invoice)
 
const char * gncInvoiceGetDocLink (const GncInvoice *invoice)
 
GncOwnerType gncInvoiceGetOwnerType (const GncInvoice *invoice)
 
GList * gncInvoiceGetTypeListForOwnerType (const GncOwnerType type)
 
GncInvoiceType gncInvoiceGetType (const GncInvoice *invoice)
 
const char * gncInvoiceGetTypeString (const GncInvoice *invoice)
 
gnc_commodity * gncInvoiceGetCurrency (const GncInvoice *invoice)
 
GncOwnergncInvoiceGetBillTo (GncInvoice *invoice)
 
gnc_numeric gncInvoiceGetToChargeAmount (const GncInvoice *invoice)
 
gboolean gncInvoiceGetActive (const GncInvoice *invoice)
 
gboolean gncInvoiceGetIsCreditNote (const GncInvoice *invoice)
 
GNCLot * gncInvoiceGetPostedLot (const GncInvoice *invoice)
 
Transaction * gncInvoiceGetPostedTxn (const GncInvoice *invoice)
 
AccountgncInvoiceGetPostedAcc (const GncInvoice *invoice)
 

Detailed Description

An invoice holds a list of entries, a pointer to the customer, and the job, the dates entered and posted, as well as the account, transaction and lot for the posted invoice.

Macro Definition Documentation

◆ GNC_ID_INVOICE

#define GNC_ID_INVOICE   "gncInvoice"

Definition at line 57 of file gncInvoice.h.

◆ GNC_INVOICE

#define GNC_INVOICE (   o)     (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_INVOICE, GncInvoice))

Definition at line 76 of file gncInvoice.h.

277{
278 if (book == NULL || guid == NULL) return NULL;
279 QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_INVOICE, GncInvoice);
280}
281
282void gncInvoiceBeginEdit (GncInvoice *invoice);
283void gncInvoiceCommitEdit (GncInvoice *invoice);
284int gncInvoiceCompare (const GncInvoice *a, const GncInvoice *b);
285gboolean gncInvoiceIsPosted (const GncInvoice *invoice);
286gboolean gncInvoiceIsPaid (const GncInvoice *invoice);
287
288#define INVOICE_ID "id"
289#define INVOICE_OWNER "owner"
290#define INVOICE_OPENED "date_opened"
291#define INVOICE_POSTED "date_posted"
292#define INVOICE_DUE "date_due"
293#define INVOICE_IS_POSTED "is_posted?"
294#define INVOICE_IS_PAID "is_paid?"
295#define INVOICE_TERMS "terms"
296#define INVOICE_BILLINGID "billing_id"
297#define INVOICE_NOTES "notes"
298#define INVOICE_DOCLINK "doclink"
299#define INVOICE_ACC "account"
300#define INVOICE_POST_TXN "posted_txn"
301#define INVOICE_POST_LOT "posted_lot"
302#define INVOICE_IS_CN "credit_note"
303#define INVOICE_TYPE "type"
304#define INVOICE_TYPE_STRING "type_string"
305#define INVOICE_BILLTO "bill-to"
306#define INVOICE_JOB "invoice_job"
307
308#define INVOICE_FROM_LOT "invoice-from-lot"
309#define INVOICE_FROM_TXN "invoice-from-txn"
310
311QofBook *gncInvoiceGetBook (GncInvoice *x);
312
314#define gncInvoiceGetGUID(x) qof_instance_get_guid (QOF_INSTANCE(x))
315#define gncInvoiceRetGUID(x) (x ? *(qof_instance_get_guid (QOF_INSTANCE(x))) : *(guid_null()))
316
318gboolean gncInvoiceEqual (const GncInvoice *a, const GncInvoice *b);
319
320#ifdef __cplusplus
321}
322#endif
323
324#endif /* GNC_INVOICE_H_ */
#define QOF_BOOK_RETURN_ENTITY(book, guid, e_type, c_type)
Encapsulates all the information about a dataset manipulated by QOF.
Definition qofbook.h:101
gboolean gncInvoiceEqual(const GncInvoice *a, const GncInvoice *b)
Test support function used by test-dbi-business-stuff.c.
QofBook reference.
Definition qofbook-p.hpp:47

◆ GNC_INVOICE_CLASS

#define GNC_INVOICE_CLASS (   k)     (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_INVOICE, GncInvoiceClass))

Definition at line 78 of file gncInvoice.h.

◆ GNC_INVOICE_GET_CLASS

#define GNC_INVOICE_GET_CLASS (   o)     (G_TYPE_INSTANCE_GET_CLASS ((o), GNC_TYPE_INVOICE, GncInvoiceClass))

Definition at line 84 of file gncInvoice.h.

◆ GNC_IS_INVOICE

#define GNC_IS_INVOICE (   o)     (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_INVOICE))

Definition at line 80 of file gncInvoice.h.

◆ GNC_IS_INVOICE_CLASS

#define GNC_IS_INVOICE_CLASS (   k)     (G_TYPE_CHECK_CLASS_TYPE ((k), GNC_TYPE_INVOICE))

Definition at line 82 of file gncInvoice.h.

◆ GNC_TYPE_INVOICE

#define GNC_TYPE_INVOICE   (gnc_invoice_get_type ())

Definition at line 75 of file gncInvoice.h.

◆ gncInvoiceGetGUID

#define gncInvoiceGetGUID (   x)    qof_instance_get_guid (QOF_INSTANCE(x))

deprecated functions

Definition at line 314 of file gncInvoice.h.

◆ gncInvoiceRetGUID

#define gncInvoiceRetGUID (   x)    (x ? *(qof_instance_get_guid (QOF_INSTANCE(x))) : *(guid_null()))

Definition at line 315 of file gncInvoice.h.

◆ INVOICE_ACC

#define INVOICE_ACC   "account"

Definition at line 299 of file gncInvoice.h.

◆ INVOICE_BILLINGID

#define INVOICE_BILLINGID   "billing_id"

Definition at line 296 of file gncInvoice.h.

◆ INVOICE_BILLTO

#define INVOICE_BILLTO   "bill-to"

Definition at line 305 of file gncInvoice.h.

◆ INVOICE_DOCLINK

#define INVOICE_DOCLINK   "doclink"

Definition at line 298 of file gncInvoice.h.

◆ INVOICE_DUE

#define INVOICE_DUE   "date_due"

Definition at line 292 of file gncInvoice.h.

◆ INVOICE_FROM_LOT

#define INVOICE_FROM_LOT   "invoice-from-lot"

Definition at line 308 of file gncInvoice.h.

◆ INVOICE_FROM_TXN

#define INVOICE_FROM_TXN   "invoice-from-txn"

Definition at line 309 of file gncInvoice.h.

◆ INVOICE_ID

#define INVOICE_ID   "id"

Definition at line 288 of file gncInvoice.h.

◆ INVOICE_IS_CN

#define INVOICE_IS_CN   "credit_note"

Definition at line 302 of file gncInvoice.h.

◆ INVOICE_IS_PAID

#define INVOICE_IS_PAID   "is_paid?"

Definition at line 294 of file gncInvoice.h.

◆ INVOICE_IS_POSTED

#define INVOICE_IS_POSTED   "is_posted?"

Definition at line 293 of file gncInvoice.h.

◆ INVOICE_JOB

#define INVOICE_JOB   "invoice_job"

Definition at line 306 of file gncInvoice.h.

◆ INVOICE_NOTES

#define INVOICE_NOTES   "notes"

Definition at line 297 of file gncInvoice.h.

◆ INVOICE_OPENED

#define INVOICE_OPENED   "date_opened"

Definition at line 290 of file gncInvoice.h.

◆ INVOICE_OWNER

#define INVOICE_OWNER   "owner"

Definition at line 289 of file gncInvoice.h.

◆ INVOICE_POST_LOT

#define INVOICE_POST_LOT   "posted_lot"

Definition at line 301 of file gncInvoice.h.

◆ INVOICE_POST_TXN

#define INVOICE_POST_TXN   "posted_txn"

Definition at line 300 of file gncInvoice.h.

◆ INVOICE_POSTED

#define INVOICE_POSTED   "date_posted"

Definition at line 291 of file gncInvoice.h.

◆ INVOICE_TERMS

#define INVOICE_TERMS   "terms"

Definition at line 295 of file gncInvoice.h.

◆ INVOICE_TYPE

#define INVOICE_TYPE   "type"

Definition at line 303 of file gncInvoice.h.

◆ INVOICE_TYPE_STRING

#define INVOICE_TYPE_STRING   "type_string"

Definition at line 304 of file gncInvoice.h.

Typedef Documentation

◆ EntryList

typedef GList EntryList

Definition at line 177 of file gncInvoice.h.

◆ GncInvoiceList

typedef GList GncInvoiceList

Definition at line 42 of file gncInvoice.h.

Enumeration Type Documentation

◆ GncInvoiceType

enum GncInvoiceType

Definition at line 59 of file gncInvoice.h.

60{
61 GNC_INVOICE_UNDEFINED ,
62 GNC_INVOICE_CUST_INVOICE , /* Invoice */
63 GNC_INVOICE_VEND_INVOICE , /* Bill */
64 GNC_INVOICE_EMPL_INVOICE , /* Voucher */
65 GNC_INVOICE_CUST_CREDIT_NOTE , /* Credit Note for a customer */
66 GNC_INVOICE_VEND_CREDIT_NOTE , /* Credit Note from a vendor */
67 GNC_INVOICE_EMPL_CREDIT_NOTE , /* Credit Note from an employee,
68 not sure this makes sense,
69 but all code is symmetrical
70 so I've added it to prevent unexpected errors */
71 GNC_INVOICE_NUM_TYPES
72} GncInvoiceType;

Function Documentation

◆ gncBillAddEntry()

void gncBillAddEntry ( GncInvoice *  bill,
GncEntry *  entry 
)

Call this function when adding an entry to a bill instead of an invoice.

Definition at line 719 of file gncInvoice.c.

720{
721 GncInvoice *old;
722
723 g_assert (bill);
724 g_assert (entry);
725 if (!bill || !entry) return;
726
727 old = gncEntryGetBill (entry);
728 if (old == bill) return; /* I already own this one */
729 if (old) gncBillRemoveEntry (old, entry);
730
731 gncInvoiceBeginEdit (bill);
732 gncEntrySetBill (entry, bill);
733 bill->entries = g_list_insert_sorted (bill->entries, entry,
734 (GCompareFunc)gncEntryCompare);
735 mark_invoice (bill);
736 gncInvoiceCommitEdit (bill);
737}

◆ gncBillRemoveEntry()

void gncBillRemoveEntry ( GncInvoice *  bill,
GncEntry *  entry 
)

Definition at line 739 of file gncInvoice.c.

740{
741 if (!bill || !entry) return;
742
743 gncInvoiceBeginEdit (bill);
744 gncEntrySetBill (entry, NULL);
745 bill->entries = g_list_remove (bill->entries, entry);
746 mark_invoice (bill);
747 gncInvoiceCommitEdit (bill);
748}

◆ gncInvoiceAddEntry()

void gncInvoiceAddEntry ( GncInvoice *  invoice,
GncEntry *  entry 
)

Definition at line 661 of file gncInvoice.c.

662{
663 GncInvoice *old;
664
665 g_assert (invoice);
666 g_assert (entry);
667 if (!invoice || !entry) return;
668
669 old = gncEntryGetInvoice (entry);
670 if (old == invoice) return; /* I already own this one */
671 if (old) gncInvoiceRemoveEntry (old, entry);
672
673 gncInvoiceBeginEdit (invoice);
674 gncEntrySetInvoice (entry, invoice);
675 invoice->entries = g_list_insert_sorted (invoice->entries, entry,
676 (GCompareFunc)gncEntryCompare);
677 mark_invoice (invoice);
678 gncInvoiceCommitEdit (invoice);
679}

◆ gncInvoiceAddPrice()

void gncInvoiceAddPrice ( GncInvoice *  invoice,
GNCPrice *  price 
)

Definition at line 692 of file gncInvoice.c.

693{
694 GList *node;
695 gnc_commodity *commodity;
696
697 if (!invoice || !price) return;
698
699 /* Keep only one price per commodity per invoice
700 * So if a price was set previously remove it first */
701 node = g_list_first (invoice->prices);
702 commodity = gnc_price_get_commodity (price);
703 while (node != NULL)
704 {
705 GNCPrice *curr = (GNCPrice*)node->data;
706 if (gnc_commodity_equal (commodity, gnc_price_get_commodity (curr)))
707 break;
708 node = g_list_next (node);
709 }
710
711 gncInvoiceBeginEdit (invoice);
712 if (node)
713 invoice->prices = g_list_delete_link (invoice->prices, node);
714 invoice->prices = g_list_prepend (invoice->prices, price);
715 mark_invoice (invoice);
716 gncInvoiceCommitEdit (invoice);
717}
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.

◆ gncInvoiceAmountPositive()

gboolean gncInvoiceAmountPositive ( const GncInvoice *  invoice)

Depending on the invoice type, invoices have a different effect on the balance.

Customer invoices increase the balance, while vendor bills decrease the balance. Credit notes have the opposite effect.

Returns TRUE if the invoice will increase the balance or FALSE otherwise.

Definition at line 1287 of file gncInvoice.c.

1288{
1289 switch (gncInvoiceGetType (invoice))
1290 {
1291 case GNC_INVOICE_CUST_INVOICE:
1292 case GNC_INVOICE_VEND_CREDIT_NOTE:
1293 case GNC_INVOICE_EMPL_CREDIT_NOTE:
1294 return TRUE;
1295 case GNC_INVOICE_CUST_CREDIT_NOTE:
1296 case GNC_INVOICE_VEND_INVOICE:
1297 case GNC_INVOICE_EMPL_INVOICE:
1298 return FALSE;
1299 case GNC_INVOICE_UNDEFINED:
1300 default:
1301 /* Should never be reached.
1302 * If it is, perhaps a new value is added to GncInvoiceType ? */
1303 g_assert_not_reached ();
1304 return FALSE;
1305 }
1306}

◆ gncInvoiceApplyPayment()

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.

It creates a lot for a payment optionally based on an existing transaction and then tries to balance it with the given invoice. Contrary to gncOwnerApplyPayment, no other open documents or payments for the owner will be considered to balance the payment.

This code is actually a convenience wrapper around gncOwnerCreatePaymentLotSecs and gncOwnerAutoApplyPaymentsWithLots. See their descriptions for more details on what happens exactly.

Definition at line 1951 of file gncInvoice.c.

1955{
1956 GNCLot *payment_lot;
1957 GList *selected_lots = NULL;
1958 const GncOwner *owner;
1959
1960 /* Verify our arguments */
1961 if (!invoice || !gncInvoiceIsPosted (invoice) || !xfer_acc) return;
1962
1963 owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
1964 g_return_if_fail (owner->owner.undefined);
1965
1966 /* Create a lot for this payment */
1967 payment_lot = gncOwnerCreatePaymentLotSecs (owner, &txn,
1968 invoice->posted_acc,
1969 xfer_acc, amount, exch,
1970 date, memo, num);
1971
1972 /* Select the invoice as only payment candidate */
1973 selected_lots = g_list_prepend (selected_lots, invoice->posted_lot);
1974
1975 /* And link the invoice lot and the payment lot together as well as possible. */
1976 if (payment_lot)
1977 selected_lots = g_list_prepend (selected_lots, payment_lot);
1978 gncOwnerAutoApplyPaymentsWithLots (owner, selected_lots);
1979}
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...
Definition gncOwner.c:1256
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.
Definition gncOwner.c:750
const GncOwner * gncOwnerGetEndOwner(const GncOwner *owner)
Get the "parent" Owner or GncGUID thereof.
Definition gncOwner.c:572

◆ gncInvoiceAutoApplyPayments()

void gncInvoiceAutoApplyPayments ( GncInvoice *  invoice)

Attempt to pay the invoice using open payment lots and lots for documents of the opposite sign (credit notes versus invoices).

Definition at line 1907 of file gncInvoice.c.

1908{
1909 GNCLot *inv_lot;
1910 Account *acct;
1911 const GncOwner *owner;
1912 GList *lot_list;
1913 struct lotmatch lm;
1914
1915 /* General note: "paying" in this context means balancing
1916 * a lot, by linking opposite signed lots together. So below the term
1917 * "payment" can both mean a true payment or it can mean a document of
1918 * the opposite sign (invoice vs credit note). It just
1919 * depends on what type of document was given as parameter
1920 * to this function. */
1921
1922 /* Payments can only be applied to posted invoices */
1923 g_return_if_fail (invoice);
1924 g_return_if_fail (invoice->posted_lot);
1925
1926 inv_lot = invoice->posted_lot;
1927 acct = invoice->posted_acc;
1928 owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
1929
1930 /* Find all lots whose balance (or part of their balance) could be
1931 * used to close this lot.
1932 * To be eligible, the lots have to have an opposite signed balance
1933 * and be for the same owner.
1934 * For example, for an invoice lot, payment lots and credit note lots
1935 * could be used. */
1936 lm.positive_balance = gnc_numeric_positive_p (gnc_lot_get_balance (inv_lot));
1937 lm.owner = owner;
1938 lot_list = xaccAccountFindOpenLots (acct, gnc_lot_match_owner_balancing,
1939 &lm, NULL);
1940
1941 lot_list = g_list_prepend (lot_list, inv_lot);
1942 gncOwnerAutoApplyPaymentsWithLots (owner, lot_list);
1943 g_list_free (lot_list);
1944}
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.
Definition Account.cpp:3982
gnc_numeric gnc_lot_get_balance(GNCLot *lot)
Returns the lot balance.
Definition gnc-lot.cpp:487
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
STRUCTS.

◆ gncInvoiceBeginEdit()

void gncInvoiceBeginEdit ( GncInvoice *  invoice)

Definition at line 1996 of file gncInvoice.c.

1997{
1998 qof_begin_edit (&invoice->inst);
1999}
gboolean qof_begin_edit(QofInstance *inst)
begin_edit

◆ gncInvoiceCommitEdit()

void gncInvoiceCommitEdit ( GncInvoice *  invoice)

Definition at line 2015 of file gncInvoice.c.

2016{
2017 if (!qof_commit_edit (QOF_INSTANCE(invoice))) return;
2018 qof_commit_edit_part2 (&invoice->inst, gncInvoiceOnError,
2019 gncInvoiceOnDone, invoice_free);
2020}
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

◆ gncInvoiceCompare()

int gncInvoiceCompare ( const GncInvoice *  a,
const GncInvoice *  b 
)

Definition at line 2022 of file gncInvoice.c.

2023{
2024 int compare;
2025
2026 if (a == b) return 0;
2027 if (!a) return -1;
2028 if (!b) return 1;
2029
2030 compare = g_strcmp0 (a->id, b->id);
2031 if (compare) return compare;
2032 if (a->date_opened != b->date_opened) return a->date_opened - b->date_opened;
2033 if (a->date_posted != b->date_posted) return a->date_posted - b->date_posted;
2034 return qof_instance_guid_compare(a, b);
2035}
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.

◆ gncInvoiceCopy()

GncInvoice * gncInvoiceCopy ( const GncInvoice *  other_invoice)

Create a new GncInvoice object as a deep copy of the given other invoice.

The returned new invoice has everything copied from the other invoice, including the ID string field. All GncEntries are newly allocated copies of the original invoice's entries.

Definition at line 336 of file gncInvoice.c.

337{
338 GncInvoice *invoice;
339 QofBook* book;
340 GList *node;
341 GValue v = G_VALUE_INIT;
342
343 g_assert (from);
344 book = qof_instance_get_book (from);
345 g_assert (book);
346
347 invoice = g_object_new (GNC_TYPE_INVOICE, NULL);
348 qof_instance_init_data (&invoice->inst, _GNC_MOD_NAME, book);
349
350 gncInvoiceBeginEdit (invoice);
351
352 invoice->id = CACHE_INSERT (from->id);
353 invoice->notes = CACHE_INSERT (from->notes);
354 invoice->billing_id = CACHE_INSERT (from->billing_id);
355 invoice->active = from->active;
356
357 qof_instance_get_kvp (QOF_INSTANCE (from), &v, 1, GNC_INVOICE_IS_CN);
358 if (G_VALUE_HOLDS_INT64 (&v))
359 qof_instance_set_kvp (QOF_INSTANCE (invoice), &v, 1, GNC_INVOICE_IS_CN);
360 g_value_unset (&v);
361
362 invoice->terms = from->terms;
363 gncBillTermIncRef (invoice->terms);
364
365 gncOwnerCopy (&from->billto, &invoice->billto);
366 gncOwnerCopy (&from->owner, &invoice->owner);
367 invoice->job = from->job; // FIXME: Need IncRef or similar here?!?
368
369 invoice->to_charge_amount = from->to_charge_amount;
370 invoice->date_opened = from->date_opened;
371
372 // Oops. Do not forget to copy the pointer to the correct currency here.
373 invoice->currency = from->currency;
374
375 gncInvoiceSetDocLink (invoice, gncInvoiceGetDocLink (from));
376
377 // Copy all invoice->entries
378 for (node = from->entries; node; node = node->next)
379 {
380 GncEntry *from_entry = node->data;
381 GncEntry *to_entry = gncEntryCreate (book);
382 gncEntryCopy (from_entry, to_entry, FALSE);
383
384 switch (gncInvoiceGetOwnerType (invoice))
385 {
386 case GNC_OWNER_VENDOR:
387 case GNC_OWNER_EMPLOYEE:
388 // this is a vendor bill, or an expense voucher
389 gncBillAddEntry (invoice, to_entry);
390 break;
391 case GNC_OWNER_CUSTOMER:
392 default:
393 // this is an invoice
394 gncInvoiceAddEntry (invoice, to_entry);
395 break;
396 }
397 }
398
399 // FIXME: The prices are not (yet) copied; is this a problem?
400
401 // Posted-date and the posted Txn is intentionally not copied; the
402 // copy isn't "posted" but needs to be posted by the user.
403 mark_invoice (invoice);
404 gncInvoiceCommitEdit (invoice);
405
406 return invoice;
407}
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
void gncBillAddEntry(GncInvoice *bill, GncEntry *entry)
Call this function when adding an entry to a bill instead of an invoice.
Definition gncInvoice.c:719
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue.
void qof_instance_set_kvp(QofInstance *, GValue const *value, unsigned count,...)
Sets a KVP slot to a value from a GValue.

◆ gncInvoiceCreate()

GncInvoice * gncInvoiceCreate ( QofBook book)

Definition at line 313 of file gncInvoice.c.

314{
315 GncInvoice *invoice;
316
317 if (!book) return NULL;
318
319 invoice = g_object_new (GNC_TYPE_INVOICE, NULL);
320 qof_instance_init_data (&invoice->inst, _GNC_MOD_NAME, book);
321
322 invoice->id = CACHE_INSERT ("");
323 invoice->notes = CACHE_INSERT ("");
324 invoice->billing_id = CACHE_INSERT ("");
325
326 invoice->billto.type = GNC_OWNER_CUSTOMER;
327 invoice->active = TRUE;
328
329 invoice->to_charge_amount = gnc_numeric_zero ();
330
331 qof_event_gen (&invoice->inst, QOF_EVENT_CREATE, NULL);
332
333 return invoice;
334}
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition qofevent.cpp:231

◆ gncInvoiceDestroy()

void gncInvoiceDestroy ( GncInvoice *  invoice)

Definition at line 409 of file gncInvoice.c.

410{
411 if (!invoice) return;
412 qof_instance_set_destroying (invoice, TRUE);
413 gncInvoiceCommitEdit (invoice);
414}

◆ gncInvoiceEqual()

gboolean gncInvoiceEqual ( const GncInvoice *  a,
const GncInvoice *  b 
)

Test support function used by test-dbi-business-stuff.c.

Definition at line 2037 of file gncInvoice.c.

2038{
2039 if (a == NULL && b == NULL) return TRUE;
2040 if (a == NULL || b == NULL) return FALSE;
2041
2042 g_return_val_if_fail (GNC_IS_INVOICE(a), FALSE);
2043 g_return_val_if_fail (GNC_IS_INVOICE(b), FALSE);
2044
2045 if (g_strcmp0 (a->id, b->id) != 0)
2046 {
2047 PWARN("IDs differ: %s vs %s", a->id, b->id);
2048 return FALSE;
2049 }
2050
2051 if (g_strcmp0 (a->notes, b->notes) != 0)
2052 {
2053 PWARN("Notes differ: %s vs %s", a->notes, b->notes);
2054 return FALSE;
2055 }
2056
2057 if (g_strcmp0 (a->billing_id, b->billing_id) != 0)
2058 {
2059 PWARN("Billing IDs differ: %s vs %s", a->billing_id, b->billing_id);
2060 return FALSE;
2061 }
2062
2063 if (g_strcmp0 (a->printname, b->printname) != 0)
2064 {
2065 PWARN("Printnames differ: %s vs %s", a->printname, b->printname);
2066 return FALSE;
2067 }
2068
2069 if (a->active != b->active)
2070 {
2071 PWARN("Active flags differ");
2072 return FALSE;
2073 }
2074
2075 if (!gncBillTermEqual (a->terms, b->terms))
2076 {
2077 PWARN("Billterms differ");
2078 return FALSE;
2079 }
2080
2081 if (!gncJobEqual (a->job, b->job))
2082 {
2083 PWARN("Jobs differ");
2084 return FALSE;
2085 }
2086
2087 if (!gnc_commodity_equal (a->currency, b->currency))
2088 {
2089 PWARN("Currencies differ");
2090 return FALSE;
2091 }
2092
2093 if (!xaccAccountEqual (a->posted_acc, b->posted_acc, TRUE))
2094 {
2095 PWARN("Posted accounts differ");
2096 return FALSE;
2097 }
2098
2099 if (!xaccTransEqual (a->posted_txn, b->posted_txn, TRUE, TRUE, TRUE, FALSE))
2100 {
2101 PWARN("Posted tx differ");
2102 return FALSE;
2103 }
2104
2105#if 0
2106 if (!gncLotEqual (a->posted_lot, b->posted_lot))
2107 {
2108 PWARN("Posted lots differ");
2109 return FALSE;
2110 }
2111#endif
2112
2113 /* FIXME: Need real checks */
2114#if 0
2115 GList *entries;
2116 GList *prices;
2117 GncOwner owner;
2118 GncOwner billto;
2119 time64 date_opened;
2120 time64 date_posted;
2121
2122 gnc_numeric to_charge_amount;
2123#endif
2124
2125 return TRUE;
2126}
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare.
Definition Account.cpp:1666
gboolean gncBillTermEqual(const GncBillTerm *a, const GncBillTerm *b)
Check if all internal fields of a and b match.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
gboolean xaccTransEqual(const Transaction *ta, const Transaction *tb, gboolean check_guids, gboolean check_splits, gboolean check_balances, gboolean assume_ordered)
Equality.
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250

◆ gncInvoiceGetActive()

gboolean gncInvoiceGetActive ( const GncInvoice *  invoice)

Definition at line 1140 of file gncInvoice.c.

1141{
1142 if (!invoice) return FALSE;
1143 return invoice->active;
1144}

◆ gncInvoiceGetBillingID()

const char * gncInvoiceGetBillingID ( const GncInvoice *  invoice)

Definition at line 864 of file gncInvoice.c.

865{
866 if (!invoice) return NULL;
867 return invoice->billing_id;
868}

◆ gncInvoiceGetBillTo()

GncOwner * gncInvoiceGetBillTo ( GncInvoice *  invoice)

Definition at line 1116 of file gncInvoice.c.

1117{
1118 if (!invoice) return NULL;
1119 return &invoice->billto;
1120}

◆ gncInvoiceGetBook()

QofBook * gncInvoiceGetBook ( GncInvoice *  x)

Definition at line 103 of file gncInvoice.c.

104{
105 return qof_instance_get_book (QOF_INSTANCE(x));
106}

◆ gncInvoiceGetCurrency()

gnc_commodity * gncInvoiceGetCurrency ( const GncInvoice *  invoice)

Definition at line 1110 of file gncInvoice.c.

1111{
1112 if (!invoice) return NULL;
1113 return invoice->currency;
1114}

◆ gncInvoiceGetDateDue()

time64 gncInvoiceGetDateDue ( const GncInvoice *  invoice)

Definition at line 849 of file gncInvoice.c.

850{
851 Transaction *txn;
852 if (!invoice) return INT64_MAX;
853 txn = gncInvoiceGetPostedTxn (invoice);
854 if (!txn) return INT64_MAX;
855 return xaccTransRetDateDue (txn);
856}
time64 xaccTransRetDateDue(const Transaction *trans)
Dates and txn-type for A/R and A/P "invoice" postings.

◆ gncInvoiceGetDateOpened()

time64 gncInvoiceGetDateOpened ( const GncInvoice *  invoice)

Definition at line 837 of file gncInvoice.c.

838{
839 if (!invoice) return INT64_MAX;
840 return invoice->date_opened;
841}

◆ gncInvoiceGetDatePosted()

time64 gncInvoiceGetDatePosted ( const GncInvoice *  invoice)

Definition at line 843 of file gncInvoice.c.

844{
845 if (!invoice) return INT64_MAX;
846 return invoice->date_posted;
847}

◆ gncInvoiceGetDocLink()

const char * gncInvoiceGetDocLink ( const GncInvoice *  invoice)

Definition at line 876 of file gncInvoice.c.

877{
878 if (!invoice) return NULL;
879
880 GValue v = G_VALUE_INIT;
881 qof_instance_get_kvp (QOF_INSTANCE(invoice), &v, 1, GNC_INVOICE_DOCLINK);
882 const char *rv = G_VALUE_HOLDS_STRING(&v) ? g_value_get_string (&v) : NULL;
883 g_value_unset (&v);
884
885 return rv;
886}

◆ gncInvoiceGetEntries()

EntryList * gncInvoiceGetEntries ( GncInvoice *  invoice)

Definition at line 1164 of file gncInvoice.c.

1165{
1166 if (!invoice) return NULL;
1167 return invoice->entries;
1168}

◆ gncInvoiceGetForeignCurrencies()

GHashTable * gncInvoiceGetForeignCurrencies ( const GncInvoice *  invoice)

Return an overview of amounts on this invoice that will be posted to accounts in currencies that are different from the invoice currency.

These accounts can be the accounts referred to in invoice entries or tax tables. This information is returned in the from of a hash table. The keys in the hash table are the foreign currencies, the values are the accumulated amounts in that currency. Drop the reference to the hash table with g_hash_table_unref when no longer needed.

Definition at line 1308 of file gncInvoice.c.

1309{
1310 EntryList *entries_iter;
1311 gboolean is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
1312 gboolean is_cn = gncInvoiceGetIsCreditNote (invoice);
1313 GHashTable *amt_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal,
1314 NULL, g_free);
1315 ENTER ("");
1316
1317 for (entries_iter = invoice->entries; entries_iter != NULL; entries_iter = g_list_next(entries_iter))
1318 {
1319 GncEntry *entry = (GncEntry*)entries_iter->data;
1320 Account *this_acc;
1321 gnc_commodity *account_currency;
1322 AccountValueList *tt_amts = NULL, *tt_iter;
1323
1324 /* Check entry's account currency */
1325 this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
1326 gncEntryGetBillAccount (entry));
1327 account_currency = xaccAccountGetCommodity (this_acc);
1328
1329 if (this_acc &&
1330 !gnc_commodity_equal (gncInvoiceGetCurrency (invoice), account_currency))
1331 {
1332 gnc_numeric *curr_amt = (gnc_numeric*) g_hash_table_lookup (amt_hash, account_currency);
1333 gnc_numeric *entry_amt = (gnc_numeric*) g_new0 (gnc_numeric, 1);
1334 *entry_amt = gncEntryGetDocValue (entry, FALSE, is_cust_doc, is_cn);
1335 if (curr_amt)
1336 *entry_amt = gnc_numeric_add (*entry_amt, *curr_amt, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP);
1337 g_hash_table_insert (amt_hash, account_currency, entry_amt);
1338 }
1339
1340 /* Check currencies of each account in the tax table linked
1341 * to the current entry */
1342 tt_amts = gncEntryGetDocTaxValues (entry, is_cust_doc, is_cn);
1343
1344 if (!tt_amts)
1345 continue;
1346
1347 for (tt_iter = tt_amts; tt_iter != NULL; tt_iter = g_list_next(tt_iter))
1348 {
1349 GncAccountValue *tt_amt_val = (GncAccountValue*)tt_iter->data;
1350 Account *tt_acc = tt_amt_val->account;
1351 gnc_commodity *tt_acc_currency = xaccAccountGetCommodity (tt_acc);
1352
1353 if (tt_acc &&
1354 !gnc_commodity_equal (gncInvoiceGetCurrency (invoice), tt_acc_currency))
1355 {
1356 gnc_numeric *curr_amt = (gnc_numeric*) g_hash_table_lookup (amt_hash, tt_acc_currency);
1357 gnc_numeric *tt_acc_amt = (gnc_numeric*) g_new0 (gnc_numeric, 1);
1358 *tt_acc_amt = tt_amt_val->value;
1359 if (curr_amt)
1360 *tt_acc_amt = gnc_numeric_add (*tt_acc_amt, *curr_amt, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP);
1361 g_hash_table_insert (amt_hash, tt_acc_currency, tt_acc_amt);
1362 }
1363 }
1364 gncAccountValueDestroy (tt_amts);
1365 }
1366
1367 LEAVE ("");
1368 return amt_hash;
1369}
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
Definition Account.cpp:3408
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.
Definition gncEntry.c:1548
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
void gncAccountValueDestroy(GList *list)
Destroy a list of accountvalues.

◆ gncInvoiceGetID()

const char * gncInvoiceGetID ( const GncInvoice *  invoice)

Definition at line 801 of file gncInvoice.c.

802{
803 if (!invoice) return NULL;
804 return invoice->id;
805}

◆ gncInvoiceGetInvoiceFromLot()

GncInvoice * gncInvoiceGetInvoiceFromLot ( GNCLot *  lot)

Given a LOT, find and return the Invoice attached to the lot.

Definition at line 1234 of file gncInvoice.c.

1235{
1236 GncGUID *guid = NULL;
1237 QofBook *book;
1238 GncInvoice *invoice = NULL;
1239
1240 if (!lot) return NULL;
1241
1242 invoice = gnc_lot_get_cached_invoice (lot);
1243 if (!invoice)
1244 {
1245 book = gnc_lot_get_book (lot);
1246 qof_instance_get (QOF_INSTANCE(lot), "invoice", &guid, NULL);
1247 invoice = gncInvoiceLookup (book, guid);
1248 guid_free (guid);
1249 gnc_lot_set_cached_invoice (lot, invoice);
1250 }
1251
1252 return invoice;
1253}
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
GncInvoice * gnc_lot_get_cached_invoice(const GNCLot *lot)
Returns the invoice with which this lot is associated.
Definition gnc-lot.cpp:385
The type used to store guids in C.
Definition guid.h:75

◆ gncInvoiceGetInvoiceFromTxn()

GncInvoice * gncInvoiceGetInvoiceFromTxn ( const Transaction *  txn)

Given a transaction, find and return the Invoice.

Definition at line 1272 of file gncInvoice.c.

1273{
1274 GncGUID *guid = NULL;
1275 QofBook *book;
1276 GncInvoice *invoice = NULL;
1277
1278 if (!txn) return NULL;
1279
1280 book = xaccTransGetBook (txn);
1281 qof_instance_get (QOF_INSTANCE (txn), "invoice", &guid, NULL);
1282 invoice = gncInvoiceLookup (book, guid);
1283 guid_free (guid);
1284 return invoice;
1285}
#define xaccTransGetBook(X)

◆ gncInvoiceGetIsCreditNote()

gboolean gncInvoiceGetIsCreditNote ( const GncInvoice *  invoice)

Definition at line 1146 of file gncInvoice.c.

1147{
1148 GValue v = G_VALUE_INIT;
1149 gboolean retval;
1150 if (!invoice) return FALSE;
1151 qof_instance_get_kvp (QOF_INSTANCE(invoice), &v, 1, GNC_INVOICE_IS_CN);
1152 retval = G_VALUE_HOLDS_INT64(&v) && g_value_get_int64 (&v);
1153 g_value_unset (&v);
1154 return retval;
1155}

◆ gncInvoiceGetNotes()

const char * gncInvoiceGetNotes ( const GncInvoice *  invoice)

Definition at line 870 of file gncInvoice.c.

871{
872 if (!invoice) return NULL;
873 return invoice->notes;
874}

◆ gncInvoiceGetOwner()

const GncOwner * gncInvoiceGetOwner ( const GncInvoice *  invoice)

Definition at line 807 of file gncInvoice.c.

808{
809 if (!invoice) return NULL;
810 return &invoice->owner;
811}

◆ gncInvoiceGetOwnerType()

GncOwnerType gncInvoiceGetOwnerType ( const GncInvoice *  invoice)

Definition at line 888 of file gncInvoice.c.

889{
890 const GncOwner *owner;
891 g_return_val_if_fail (invoice, GNC_OWNER_NONE);
892
893 owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
894 return (gncOwnerGetType (owner));
895}
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition gncOwner.c:200

◆ gncInvoiceGetPostedAcc()

Account * gncInvoiceGetPostedAcc ( const GncInvoice *  invoice)

Definition at line 1134 of file gncInvoice.c.

1135{
1136 if (!invoice) return NULL;
1137 return invoice->posted_acc;
1138}

◆ gncInvoiceGetPostedLot()

GNCLot * gncInvoiceGetPostedLot ( const GncInvoice *  invoice)

Definition at line 1122 of file gncInvoice.c.

1123{
1124 if (!invoice) return NULL;
1125 return invoice->posted_lot;
1126}

◆ gncInvoiceGetPostedTxn()

Transaction * gncInvoiceGetPostedTxn ( const GncInvoice *  invoice)

Definition at line 1128 of file gncInvoice.c.

1129{
1130 if (!invoice) return NULL;
1131 return invoice->posted_txn;
1132}

◆ gncInvoiceGetPrice()

GNCPrice * gncInvoiceGetPrice ( GncInvoice *  invoice,
gnc_commodity *  commodity 
)

Definition at line 1170 of file gncInvoice.c.

1171{
1172 GList *node = g_list_first (invoice->prices);
1173
1174 while (node != NULL)
1175 {
1176 GNCPrice *curr = (GNCPrice*)node->data;
1177
1178 if (gnc_commodity_equal (commodity, gnc_price_get_commodity (curr)))
1179 return curr;
1180
1181 node = g_list_next (node);
1182 }
1183
1184 return NULL;
1185}

◆ gncInvoiceGetTerms()

GncBillTerm * gncInvoiceGetTerms ( const GncInvoice *  invoice)

Definition at line 858 of file gncInvoice.c.

859{
860 if (!invoice) return NULL;
861 return invoice->terms;
862}

◆ gncInvoiceGetToChargeAmount()

gnc_numeric gncInvoiceGetToChargeAmount ( const GncInvoice *  invoice)

Definition at line 1158 of file gncInvoice.c.

1159{
1160 if (!invoice) return gnc_numeric_zero ();
1161 return invoice->to_charge_amount;
1162}

◆ gncInvoiceGetTotal()

gnc_numeric gncInvoiceGetTotal ( GncInvoice *  invoice)

Return the "total" amount of the invoice as seen on the document (and shown to the user in the reports and invoice ledger).

Definition at line 1008 of file gncInvoice.c.

1009{
1010 if (!invoice) return gnc_numeric_zero ();
1011 return gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, FALSE, 0);
1012}

◆ gncInvoiceGetTotalOf()

gnc_numeric gncInvoiceGetTotalOf ( GncInvoice *  invoice,
GncEntryPaymentType  type 
)

Definition at line 1026 of file gncInvoice.c.

1027{
1028 if (!invoice) return gnc_numeric_zero ();
1029 return gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, TRUE, type);
1030}

◆ gncInvoiceGetTotalSubtotal()

gnc_numeric gncInvoiceGetTotalSubtotal ( GncInvoice *  invoice)

Definition at line 1014 of file gncInvoice.c.

1015{
1016 if (!invoice) return gnc_numeric_zero ();
1017 return gncInvoiceGetTotalInternal (invoice, TRUE, FALSE, FALSE, 0);
1018}

◆ gncInvoiceGetTotalTax()

gnc_numeric gncInvoiceGetTotalTax ( GncInvoice *  invoice)

Definition at line 1020 of file gncInvoice.c.

1021{
1022 if (!invoice) return gnc_numeric_zero ();
1023 return gncInvoiceGetTotalInternal (invoice, FALSE, TRUE, FALSE, 0);
1024}

◆ gncInvoiceGetTotalTaxList()

AccountValueList * gncInvoiceGetTotalTaxList ( GncInvoice *  invoice)

Return a list of tax totals accumulated per tax account.

Definition at line 1032 of file gncInvoice.c.

1033{
1034 AccountValueList *taxes;
1035 if (!invoice) return NULL;
1036
1037 gncInvoiceGetNetAndTaxesInternal (invoice, FALSE, &taxes, FALSE, 0);
1038 return taxes;
1039}

◆ gncInvoiceGetType()

GncInvoiceType gncInvoiceGetType ( const GncInvoice *  invoice)

Definition at line 1065 of file gncInvoice.c.

1066{
1067 if (!invoice) return GNC_INVOICE_UNDEFINED;
1068 switch (gncInvoiceGetOwnerType (invoice))
1069 {
1070 case GNC_OWNER_CUSTOMER:
1071 return (gncInvoiceGetIsCreditNote (invoice) ?
1072 GNC_INVOICE_CUST_CREDIT_NOTE :
1073 GNC_INVOICE_CUST_INVOICE);
1074 case GNC_OWNER_VENDOR:
1075 return (gncInvoiceGetIsCreditNote (invoice) ?
1076 GNC_INVOICE_VEND_CREDIT_NOTE :
1077 GNC_INVOICE_VEND_INVOICE);
1078 case GNC_OWNER_EMPLOYEE:
1079 return (gncInvoiceGetIsCreditNote (invoice) ?
1080 GNC_INVOICE_EMPL_CREDIT_NOTE :
1081 GNC_INVOICE_EMPL_INVOICE);
1082 default:
1083 PWARN ("No invoice types defined for owner %d",
1084 gncInvoiceGetOwnerType (invoice));
1085 return GNC_INVOICE_UNDEFINED;
1086 }
1087}

◆ gncInvoiceGetTypeListForOwnerType()

GList * gncInvoiceGetTypeListForOwnerType ( const GncOwnerType  type)

Definition at line 1041 of file gncInvoice.c.

1042{
1043 GList *type_list = NULL;
1044 switch (type)
1045 {
1046 case GNC_OWNER_CUSTOMER:
1047 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_CUST_INVOICE));
1048 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_CUST_CREDIT_NOTE));
1049 return type_list;
1050 case GNC_OWNER_VENDOR:
1051 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_VEND_INVOICE));
1052 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_VEND_CREDIT_NOTE));
1053 return type_list;
1054 case GNC_OWNER_EMPLOYEE:
1055 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_EMPL_INVOICE));
1056 type_list = g_list_append (type_list, GINT_TO_POINTER(GNC_INVOICE_EMPL_CREDIT_NOTE));
1057 return type_list;
1058 default:
1059 PWARN("Bad owner type, no invoices.");
1060 return NULL;
1061 }
1062
1063}

◆ gncInvoiceGetTypeString()

const char * gncInvoiceGetTypeString ( const GncInvoice *  invoice)

Definition at line 1089 of file gncInvoice.c.

1090{
1091 GncInvoiceType type = gncInvoiceGetType (invoice);
1092 switch (type)
1093 {
1094 case GNC_INVOICE_CUST_INVOICE:
1095 return _("Invoice");
1096 case GNC_INVOICE_VEND_INVOICE:
1097 return _("Bill");
1098 case GNC_INVOICE_EMPL_INVOICE:
1099 return _("Expense");
1100 case GNC_INVOICE_CUST_CREDIT_NOTE:
1101 case GNC_INVOICE_VEND_CREDIT_NOTE:
1102 case GNC_INVOICE_EMPL_CREDIT_NOTE:
1103 return _("Credit Note");
1104 default:
1105 PWARN("Unknown invoice type");
1106 return NULL;
1107 }
1108}

◆ gncInvoiceIsPaid()

gboolean gncInvoiceIsPaid ( const GncInvoice *  invoice)

Definition at line 1987 of file gncInvoice.c.

1988{
1989 if (!invoice) return FALSE;
1990 if (!invoice->posted_lot) return FALSE;
1991 return gnc_lot_is_closed (invoice->posted_lot);
1992}
gboolean gnc_lot_is_closed(GNCLot *lot)
Returns closed status of the given lot.
Definition gnc-lot.cpp:367

◆ gncInvoiceIsPosted()

gboolean gncInvoiceIsPosted ( const GncInvoice *  invoice)

Definition at line 1981 of file gncInvoice.c.

1982{
1983 if (!invoice) return FALSE;
1984 return GNC_IS_TRANSACTION(gncInvoiceGetPostedTxn (invoice));
1985}

◆ gncInvoicePostToAccount()

Transaction * gncInvoicePostToAccount ( GncInvoice *  invoice,
Account acc,
time64  posted_date,
time64  due_date,
const char *  memo,
gboolean  accumulatesplits,
gboolean  autopay 
)

Post this invoice to an account.

Returns the new Transaction that is tied to this invoice. The transaction is set with the supplied posted date, due date, and memo. The Transaction description is set to the name of the company.

If accumulate splits is TRUE, entries in the same account will be merged into one single split in that account. Otherwise each entry will be posted as a separate split, possibly resulting in multiple splits in one account.

If autopay is TRUE, the code will try to find pre-payments, invoices or credit notes that can reduce the amount due for this invoice, marking the invoice as fully or partially paid, depending on the amounts on all documents involved. If autopay is FALSE, it's the user's responsibility to explicitly pay the invoice.

Definition at line 1442 of file gncInvoice.c.

1446{
1447 Transaction *txn;
1448 QofBook *book;
1449 GNCLot *lot = NULL;
1450 GList *iter;
1451 GList *splitinfo = NULL;
1452 gnc_numeric total;
1453 gboolean is_cust_doc;
1454 gboolean is_cn;
1455 const char *name, *type;
1456 char *lot_title;
1457 Account *ccard_acct = NULL;
1458 const GncOwner *owner;
1459 int denom = xaccAccountGetCommoditySCU (acc);
1460 AccountValueList *taxes;
1461
1462 if (!invoice || !acc) return NULL;
1463 if (gncInvoiceIsPosted (invoice)) return NULL;
1464
1465 ENTER ("");
1466 gncInvoiceBeginEdit (invoice);
1467 book = qof_instance_get_book (invoice);
1468
1469 /* Stabilize the Billing Terms of this invoice */
1470 if (invoice->terms)
1471 gncInvoiceSetTerms (invoice,
1472 gncBillTermReturnChild (invoice->terms, TRUE));
1473
1474 /* GncEntry functions need to know if the invoice/credit note is for a customer or a vendor/employee. */
1475 is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
1476 is_cn = gncInvoiceGetIsCreditNote (invoice);
1477
1478 /* Figure out if we need to separate out "credit-card" items */
1479 owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
1480 if (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_EMPLOYEE)
1481 ccard_acct = gncEmployeeGetCCard (gncOwnerGetEmployee (owner));
1482
1483 /* Create a new lot for this invoice */
1484 lot = gnc_lot_new (book);
1485 gncInvoiceAttachToLot (invoice, lot);
1486 gnc_lot_begin_edit (lot);
1487
1488 type = gncInvoiceGetTypeString (invoice);
1489
1490 /* Set the lot title */
1491 lot_title = g_strdup_printf ("%s %s", type, gncInvoiceGetID (invoice));
1492 gnc_lot_set_title (lot, lot_title);
1493 g_free (lot_title);
1494
1495 /* Create a new transaction */
1496 txn = xaccMallocTransaction (book);
1497 xaccTransBeginEdit (txn);
1498
1499 name = gncOwnerGetName (gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice)));
1500
1501 /* Set Transaction Description (Owner Name) , Num (invoice ID or type, based
1502 * on book option), Currency */
1503 xaccTransSetDescription (txn, name ? name : "");
1504 gnc_set_num_action (txn, NULL, gncInvoiceGetID (invoice), type);
1505 xaccTransSetCurrency (txn, invoice->currency);
1506
1507 /* Entered and Posted at date */
1509 xaccTransSetDatePostedSecsNormalized (txn, post_date);
1510 gncInvoiceSetDatePosted (invoice, xaccTransRetDatePosted(txn));
1511
1512 xaccTransSetDateDue (txn, due_date);
1513
1514 /* Get invoice total and taxes. */
1515 total = gncInvoiceGetTotal (invoice);
1516 taxes = gncInvoiceGetTotalTaxList (invoice);
1517 /* The two functions above return signs relative to the document
1518 * We need to convert them to balance values before we can use them here
1519 * Note the odd construct comparing two booleans is to xor them
1520 * that is, only evaluate true if both are different.
1521 */
1522 if (is_cust_doc != is_cn)
1523 {
1524 GList *node;
1525 total = gnc_numeric_neg (total);
1526 for (node = taxes; node; node = node->next)
1527 {
1528 GncAccountValue *acc_val = node->data;
1529 acc_val->value = gnc_numeric_neg (acc_val->value);
1530 }
1531 }
1532
1533 /* Iterate through the entries; sum up everything for each account.
1534 * then create the appropriate splits in this txn.
1535 */
1536
1537 for (iter = gncInvoiceGetEntries (invoice); iter; iter = iter->next)
1538 {
1539 gnc_numeric value, tax;
1540 GncEntry * entry = iter->data;
1541 Account *this_acc;
1542
1543 /* Stabilize the TaxTable in this entry */
1544 gncEntryBeginEdit (entry);
1545 if (is_cust_doc)
1546 gncEntrySetInvTaxTable
1547 (entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE));
1548 else
1549 {
1550 gncEntrySetBillTaxTable
1551 (entry, gncTaxTableReturnChild (gncEntryGetBillTaxTable (entry), TRUE));
1552
1553 /* If this is a bill, and the entry came from an invoice originally, copy the price */
1554 if (gncEntryGetBillable (entry))
1555 {
1556 /* We need to set the net price since it may be another tax rate for invoices than bills */
1557 gncEntrySetInvPrice (entry, gncEntryGetPrice (entry, FALSE, TRUE));
1558 gncEntrySetInvTaxIncluded (entry, FALSE);
1559 }
1560 }
1561 gncEntryCommitEdit (entry);
1562
1563 /* Obtain the Entry's Value and TaxValues
1564 Note we use rounded values here and below to prevent creating an imbalanced transaction */
1565 value = gncEntryGetBalValue (entry, TRUE, is_cust_doc);
1566 tax = gncEntryGetBalTaxValue (entry, TRUE, is_cust_doc);
1567
1568 DEBUG ("Tax %" PRId64 "/%" PRId64 " on entry value %" PRId64 "/%" PRId64,
1569 tax.num, tax.denom, value.num, value.denom);
1570 /* add the value for the account split */
1571 this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
1572 gncEntryGetBillAccount (entry));
1573 if (this_acc)
1574 {
1575 if (gnc_numeric_check (value) == GNC_ERROR_OK)
1576 {
1577 if (accumulatesplits)
1578 splitinfo = gncAccountValueAdd (splitinfo, this_acc, value);
1579 /* Adding to total in case of accumulatesplits will be deferred to later when each split is effectively added */
1580 else if (!gncInvoicePostAddSplit (book, this_acc, txn, value,
1581 gncEntryGetDescription (entry),
1582 type, invoice))
1583 {
1584 /*This is an error, which shouldn't even be able to happen.
1585 We can't really do anything sensible about it, and this is
1586 a user-interface free zone so we can't try asking the user
1587 again either, have to return NULL*/
1588 PERR("Failed to add split %s", gncEntryGetDescription (entry));
1589 LEAVE ("NULL");
1590 return NULL;
1591 }
1592
1593 /* If there is a credit-card account, and this is a CCard
1594 * payment type, subtract it from the total, and instead
1595 * create a split to the CC Acct with a memo of the entry
1596 * description instead of the provided memo. Note that the
1597 * value reversal is the same as the post account.
1598 *
1599 * Note: we don't have to worry about the tax values --
1600 * expense vouchers don't have them.
1601 */
1602 if (ccard_acct && gncEntryGetBillPayment (entry) == GNC_PAYMENT_CARD)
1603 {
1604 Split *split;
1605
1606 total = gnc_numeric_sub (total, value, denom,
1607 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
1608
1609 split = xaccMallocSplit (book);
1610 xaccSplitSetMemo (split, gncEntryGetDescription (entry));
1611 /* set action based on book option */
1612 gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
1613 xaccAccountBeginEdit (ccard_acct);
1614 xaccAccountInsertSplit (ccard_acct, split);
1615 xaccAccountCommitEdit (ccard_acct);
1616 xaccTransAppendSplit (txn, split);
1617 xaccSplitSetBaseValue (split, gnc_numeric_neg (value),
1618 invoice->currency);
1619
1620 }
1621
1622 }
1623 else
1624 PWARN ("bad value in our entry");
1625 }
1626
1627 /* check the taxes */
1628 if (gnc_numeric_check (tax) != GNC_ERROR_OK)
1629 PWARN ("bad tax in our entry");
1630
1631 } /* for */
1632
1633
1634 /* now merge in the TaxValues */
1635 splitinfo = gncAccountValueAddList (splitinfo, taxes);
1636 gncAccountValueDestroy (taxes);
1637
1638 /* Iterate through the splitinfo list and generate the splits */
1639 if (splitinfo)
1640 PINFO ("Processing Split List");
1641 for (iter = splitinfo; iter; iter = iter->next)
1642 {
1643 GncAccountValue *acc_val = iter->data;
1644
1645 //gnc_numeric amt_rounded = gnc_numeric_convert(acc_val->value,
1646 // denom, GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
1647 if (!gncInvoicePostAddSplit (book, acc_val->account, txn, acc_val->value,
1648 memo, type, invoice))
1649 {
1650 /*This is an error, which shouldn't even be able to happen.
1651 We can't really do anything sensible about it, and this is
1652 a user-interface free zone so we can't try asking the user
1653 again either, have to return NULL*/
1654 PERR("Failed to add split %s, aborting accumulated splits.", memo);
1655 return NULL;
1656 }
1657 }
1658
1659 /* If there is a ccard account, we may have an additional "to_card" payment.
1660 * we should make that now.
1661 */
1662 if (ccard_acct && !gnc_numeric_zero_p (invoice->to_charge_amount))
1663 {
1664 Split *split = xaccMallocSplit (book);
1665
1666 /* To charge amount is stored in document value. We need balance value here
1667 * so convert if necessary. */
1668 gnc_numeric to_charge_bal_amount = (is_cn ? gnc_numeric_neg (invoice->to_charge_amount)
1669 : invoice->to_charge_amount);
1670
1671 PINFO ("Process to_card payment split");
1672 /* Set memo. */
1673 xaccSplitSetMemo (split, _("Extra to Charge Card"));
1674 /* Set action based on book option */
1675 gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
1676
1677 xaccAccountBeginEdit (ccard_acct);
1678 xaccAccountInsertSplit (ccard_acct, split);
1679 xaccAccountCommitEdit (ccard_acct);
1680 xaccTransAppendSplit (txn, split);
1681 xaccSplitSetBaseValue (split, gnc_numeric_neg (to_charge_bal_amount),
1682 invoice->currency);
1683
1684 total = gnc_numeric_sub (total, to_charge_bal_amount, denom,
1685 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
1686 }
1687
1688 /* Now create the Posted split (which is the opposite sign of the above splits) */
1689 {
1690 Split *split = xaccMallocSplit (book);
1691
1692 PINFO ("Process to_card balancing split");
1693 /* Set memo */
1694 xaccSplitSetMemo (split, memo);
1695 /* Set action based on book option */
1696 gnc_set_num_action (NULL, split, gncInvoiceGetID (invoice), type);
1697
1699 xaccAccountInsertSplit (acc, split);
1701 xaccTransAppendSplit (txn, split);
1702 xaccSplitSetBaseValue (split, gnc_numeric_neg (total),
1703 invoice->currency);
1704
1705 /* add this split to the lot */
1706 gnc_lot_add_split (lot, split);
1707 }
1708
1709 /* Now attach this invoice to the txn and account */
1710 gncInvoiceAttachToTxn (invoice, txn);
1711 gncInvoiceSetPostedAcc (invoice, acc);
1712
1713 xaccTransSetReadOnly (txn, _("Generated from an invoice. Try unposting the invoice."));
1714 xaccTransCommitEdit (txn);
1715
1716 gncAccountValueDestroy (splitinfo);
1717
1718 gnc_lot_commit_edit (lot);
1719 /* Not strictly necessary, since it was done by the Set calls
1720 * above, but good insurance. */
1721 DEBUG("Committing Invoice %s", invoice->id);
1722 mark_invoice (invoice);
1723 gncInvoiceCommitEdit (invoice);
1724
1725 /* If requested, attempt to automatically apply open payments
1726 * and reverse documents to this lot to close it (or at least
1727 * reduce its balance) */
1728 if (autopay)
1730
1731 LEAVE ("");
1732 return txn;
1733}
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition Account.cpp:1516
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition Account.cpp:1475
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
Definition Account.cpp:2745
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction.
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3)).
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account.
Definition Account.h:1069
void xaccTransSetReadOnly(Transaction *trans, const char *reason)
Set the transaction to be ReadOnly by setting a non-NULL value as "reason".
void xaccTransSetDateDue(Transaction *trans, time64 time)
Dates and txn-type for A/R and A/P "invoice" postings.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
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...
AccountValueList * gncInvoiceGetTotalTaxList(GncInvoice *invoice)
Return a list of tax totals accumulated per tax account.
void gncInvoiceAutoApplyPayments(GncInvoice *invoice)
Attempt to pay the invoice using open payment lots and lots for documents of the opposite sign (credi...
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264
#define PERR(format, args...)
Log a serious error.
Definition qoflog.h:244
void gnc_lot_add_split(GNCLot *lot, Split *split)
Adds a split to this lot.
Definition gnc-lot.cpp:579
gnc_numeric gnc_numeric_sub(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.
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_ERROR_OK
No error.
GncEmployee * gncOwnerGetEmployee(const GncOwner *owner)
If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object.
Definition gncOwner.c:390
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.
GList * gncAccountValueAddList(GList *l1, GList *l2)
Merge l2 into l1.
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
Split * xaccMallocSplit(QofBook *book)
Constructor.
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...
Definition Split.cpp:1355

◆ gncInvoiceRemoveEntries()

void gncInvoiceRemoveEntries ( GncInvoice *  invoice)

Remove all entries from an invoice.

To be called before destroying an invoice.

Definition at line 760 of file gncInvoice.c.

761{
762 if (!invoice) return;
763
764 // gnc{Bill,Invoice}RemoveEntry free the "entry" node.
765 // Make sure to save "next" first.
766 for (GList *next, *node = invoice->entries; node; node = next)
767 {
768 next = node->next;
769 GncEntry *entry = node->data;
770
771 switch (gncInvoiceGetOwnerType (invoice))
772 {
773 case GNC_OWNER_VENDOR:
774 case GNC_OWNER_EMPLOYEE:
775 // this is a vendor bill, or an expense voucher
776 gncBillRemoveEntry (invoice, entry);
777 break;
778 case GNC_OWNER_CUSTOMER:
779 default:
780 // this is an invoice
781 gncInvoiceRemoveEntry (invoice, entry);
782 break;
783 }
784
785 /* If the entry is no longer referenced by any document,
786 * remove it.
787 */
788 if (!(gncEntryGetInvoice (entry) ||
789 gncEntryGetBill (entry) ||
790 gncEntryGetOrder (entry)))
791 {
792 gncEntryBeginEdit (entry);
793 gncEntryDestroy (entry);
794 }
795 }
796}

◆ gncInvoiceRemoveEntry()

void gncInvoiceRemoveEntry ( GncInvoice *  invoice,
GncEntry *  entry 
)

Definition at line 681 of file gncInvoice.c.

682{
683 if (!invoice || !entry) return;
684
685 gncInvoiceBeginEdit (invoice);
686 gncEntrySetInvoice (entry, NULL);
687 invoice->entries = g_list_remove (invoice->entries, entry);
688 mark_invoice (invoice);
689 gncInvoiceCommitEdit (invoice);
690}

◆ gncInvoiceSetActive()

void gncInvoiceSetActive ( GncInvoice *  invoice,
gboolean  active 
)

Definition at line 566 of file gncInvoice.c.

567{
568 if (!invoice) return;
569 if (invoice->active == active) return;
570 gncInvoiceBeginEdit (invoice);
571 invoice->active = active;
572 mark_invoice (invoice);
573 gncInvoiceCommitEdit (invoice);
574}

◆ gncInvoiceSetBillingID()

void gncInvoiceSetBillingID ( GncInvoice *  invoice,
const char *  billing_id 
)

Definition at line 528 of file gncInvoice.c.

529{
530 if (!invoice) return;
531 SET_STR (invoice, invoice->billing_id, billing_id);
532 mark_invoice (invoice);
533 gncInvoiceCommitEdit (invoice);
534}

◆ gncInvoiceSetBillTo()

void gncInvoiceSetBillTo ( GncInvoice *  invoice,
GncOwner billto 
)

Definition at line 607 of file gncInvoice.c.

608{
609 if (!invoice || !billto) return;
610 if (gncOwnerEqual (&invoice->billto, billto)) return;
611
612 gncInvoiceBeginEdit (invoice);
613 gncOwnerCopy (billto, &invoice->billto);
614 mark_invoice (invoice);
615 gncInvoiceCommitEdit (invoice);
616}
gboolean gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking.
Definition gncOwner.c:404

◆ gncInvoiceSetCurrency()

void gncInvoiceSetCurrency ( GncInvoice *  invoice,
gnc_commodity *  currency 
)

Definition at line 595 of file gncInvoice.c.

596{
597 if (!invoice || !currency) return;
598 if (invoice->currency &&
599 gnc_commodity_equal (invoice->currency, currency))
600 return;
601 gncInvoiceBeginEdit (invoice);
602 invoice->currency = currency;
603 mark_invoice (invoice);
604 gncInvoiceCommitEdit (invoice);
605}

◆ gncInvoiceSetDateOpened()

void gncInvoiceSetDateOpened ( GncInvoice *  invoice,
time64  date 
)

Definition at line 494 of file gncInvoice.c.

495{
496 if (!invoice) return;
497 if (date == invoice->date_opened) return;
498 gncInvoiceBeginEdit (invoice);
499 invoice->date_opened = date;
500 mark_invoice (invoice);
501 gncInvoiceCommitEdit (invoice);
502}

◆ gncInvoiceSetDateOpenedGDate()

void gncInvoiceSetDateOpenedGDate ( GncInvoice *  invoice,
const GDate *  date 
)

Set the DateOpened using a GDate argument.

(Note: Internally this stores the date in a time64 as created through time64CanonicalDayTime()).

Definition at line 488 of file gncInvoice.c.

489{
490 g_assert (date);
491 gncInvoiceSetDateOpened(invoice, time64CanonicalDayTime (gdate_to_time64 (*date)));
492}
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
time64 time64CanonicalDayTime(time64 t)
convert a time64 on a certain day (localtime) to the time64 representing midday on that day.
Definition gnc-date.cpp:404

◆ gncInvoiceSetDatePosted()

void gncInvoiceSetDatePosted ( GncInvoice *  invoice,
time64  date 
)

Definition at line 504 of file gncInvoice.c.

505{
506 if (!invoice) return;
507 if (date == invoice->date_posted) return;
508 gncInvoiceBeginEdit (invoice);
509 invoice->date_posted = date;
510 mark_invoice (invoice);
511 gncInvoiceCommitEdit (invoice);
512}

◆ gncInvoiceSetDocLink()

void gncInvoiceSetDocLink ( GncInvoice *  invoice,
const char *  doclink 
)

Definition at line 544 of file gncInvoice.c.

545{
546 if (!invoice || !doclink) return;
547
548 gncInvoiceBeginEdit (invoice);
549
550 if (doclink[0] == '\0')
551 {
552 qof_instance_set_kvp (QOF_INSTANCE (invoice), NULL, 1, GNC_INVOICE_DOCLINK);
553 }
554 else
555 {
556 GValue v = G_VALUE_INIT;
557 g_value_init (&v, G_TYPE_STRING);
558 g_value_set_static_string (&v, doclink);
559 qof_instance_set_kvp (QOF_INSTANCE (invoice), &v, 1, GNC_INVOICE_DOCLINK);
560 g_value_unset (&v);
561 }
562 qof_instance_set_dirty (QOF_INSTANCE(invoice));
563 gncInvoiceCommitEdit (invoice);
564}

◆ gncInvoiceSetID()

void gncInvoiceSetID ( GncInvoice *  invoice,
const char *  id 
)

Definition at line 444 of file gncInvoice.c.

445{
446 if (!invoice || !id) return;
447 SET_STR (invoice, invoice->id, id);
448 mark_invoice (invoice);
449 gncInvoiceCommitEdit (invoice);
450}

◆ gncInvoiceSetIsCreditNote()

void gncInvoiceSetIsCreditNote ( GncInvoice *  invoice,
gboolean  credit_note 
)

Definition at line 576 of file gncInvoice.c.

577{
578 GValue v = G_VALUE_INIT;
579 if (!invoice) return;
580 gncInvoiceBeginEdit (invoice);
581 g_value_init (&v, G_TYPE_INT64);
582 g_value_set_int64 (&v, credit_note ? 1 : 0);
583 qof_instance_set_kvp (QOF_INSTANCE (invoice), &v, 1, GNC_INVOICE_IS_CN);
584 g_value_unset (&v);
585 mark_invoice (invoice);
586 gncInvoiceCommitEdit (invoice);
587
588 /* If this is a credit note, set a feature flag for it in the book
589 * This will prevent older GnuCash versions that don't support
590 * credit notes to open this file. */
591 if (credit_note)
592 gnc_features_set_used (gncInvoiceGetBook (invoice), GNC_FEATURE_CREDIT_NOTES);
593}
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.

◆ gncInvoiceSetNotes()

void gncInvoiceSetNotes ( GncInvoice *  invoice,
const char *  notes 
)

Definition at line 536 of file gncInvoice.c.

537{
538 if (!invoice || !notes) return;
539 SET_STR (invoice, invoice->notes, notes);
540 mark_invoice (invoice);
541 gncInvoiceCommitEdit (invoice);
542}

◆ gncInvoiceSetOwner()

void gncInvoiceSetOwner ( GncInvoice *  invoice,
GncOwner owner 
)

Definition at line 452 of file gncInvoice.c.

453{
454 if (!invoice || !owner) return;
455 if (gncOwnerEqual (&invoice->owner, owner)) return;
456 gncInvoiceBeginEdit (invoice);
457 gncOwnerCopy (owner, &invoice->owner);
458 mark_invoice (invoice);
459 gncInvoiceCommitEdit (invoice);
460}

◆ gncInvoiceSetTerms()

void gncInvoiceSetTerms ( GncInvoice *  invoice,
GncBillTerm *  terms 
)

Definition at line 514 of file gncInvoice.c.

515{
516 if (!invoice) return;
517 if (invoice->terms == terms) return;
518 gncInvoiceBeginEdit (invoice);
519 if (invoice->terms)
520 gncBillTermDecRef (invoice->terms);
521 invoice->terms = terms;
522 if (invoice->terms)
523 gncBillTermIncRef (invoice->terms);
524 mark_invoice (invoice);
525 gncInvoiceCommitEdit (invoice);
526}

◆ gncInvoiceSetToChargeAmount()

void gncInvoiceSetToChargeAmount ( GncInvoice *  invoice,
gnc_numeric  amount 
)

Definition at line 618 of file gncInvoice.c.

619{
620 if (!invoice) return;
621 if (gnc_numeric_equal (invoice->to_charge_amount, amount)) return;
622 gncInvoiceBeginEdit (invoice);
623 invoice->to_charge_amount = amount;
624 mark_invoice (invoice);
625 gncInvoiceCommitEdit (invoice);
626}
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.

◆ gncInvoiceSortEntries()

void gncInvoiceSortEntries ( GncInvoice *  invoice)

Call this function when an Entry is changed and you want to re-sort the list of entries.

Definition at line 750 of file gncInvoice.c.

751{
752 if (!invoice) return;
753 invoice->entries = g_list_sort (invoice->entries,
754 (GCompareFunc)gncEntryCompare);
755 gncInvoiceBeginEdit (invoice);
756 mark_invoice (invoice);
757 gncInvoiceCommitEdit (invoice);
758}

◆ gncInvoiceUnpost()

gboolean gncInvoiceUnpost ( GncInvoice *  invoice,
gboolean  reset_tax_tables 
)

Unpost this invoice.

This will destroy the posted transaction and return the invoice to its unposted state. It may leave empty lots out there. If reset_tax_tables is TRUE, then it will also revert all the Tax Tables to the parent, which will potentially change the total value of the invoice. It may also leave some orphaned Tax Table children.

Returns TRUE if successful, FALSE if there is a problem.

Definition at line 1736 of file gncInvoice.c.

1737{
1738 Transaction *txn;
1739 GNCLot *lot;
1740 GList *lot_split_list, *lot_split_iter;
1741
1742 if (!invoice) return FALSE;
1743 if (!gncInvoiceIsPosted (invoice)) return FALSE;
1744
1745 txn = gncInvoiceGetPostedTxn (invoice);
1746 g_return_val_if_fail (txn, FALSE);
1747
1748 lot = gncInvoiceGetPostedLot (invoice);
1749 g_return_val_if_fail (lot, FALSE);
1750
1751 ENTER ("");
1752 /* Destroy the Posted Transaction */
1753 xaccTransClearReadOnly (txn);
1754 xaccTransBeginEdit (txn);
1755 xaccTransDestroy (txn);
1756 xaccTransCommitEdit (txn);
1757
1758 /* Disconnect the lot from the invoice; re-attach to the invoice owner */
1759 gncInvoiceDetachFromLot (lot);
1760 gncOwnerAttachToLot (&invoice->owner, lot);
1761
1762 /* Check if this invoice was linked to other lots (payments/inverse signed
1763 * invoices).
1764 * If this is the case, recreate the link transaction between all the remaining lots.
1765 *
1766 * Note that before GnuCash 2.6 payments were not stored in separate lots, but
1767 * always ended up in invoice lots when matched to an invoice. Over-payments
1768 * were copied to a new lot, to which later an invoice was added again and so on.
1769 * These over-payments were handled with automatic payment forward transactions.
1770 * You could consider these transactions to be links between lots as well, but
1771 * to avoid some unexpected behavior, these will not be altered here.
1772 */
1773
1774 // Note: make a copy of the lot list here, when splits are deleted from the lot,
1775 // the original list may be destroyed by the lot code.
1776 lot_split_list = g_list_copy (gnc_lot_get_split_list (lot));
1777 if (lot_split_list)
1778 PINFO ("Recreating link transactions for remaining lots");
1779 for (lot_split_iter = lot_split_list; lot_split_iter; lot_split_iter = lot_split_iter->next)
1780 {
1781 Split *split = lot_split_iter->data;
1782 GList *other_split_list, *list_iter;
1783 Transaction *other_txn = xaccSplitGetParent (split);
1784 GList *lot_list = NULL;
1785
1786 /* Only work with transactions that link invoices and payments.
1787 * Note: this check also catches the possible case of NULL splits. */
1788 if (xaccTransGetTxnType (other_txn) != TXN_TYPE_LINK)
1789 continue;
1790
1791 /* Save a list of lots this linking transaction linked to */
1792 other_split_list = xaccTransGetSplitList (other_txn);
1793 for (list_iter = other_split_list; list_iter; list_iter = list_iter->next)
1794 {
1795 Split *other_split = list_iter->data;
1796 GNCLot *other_lot = xaccSplitGetLot (other_split);
1797
1798 /* Omit the lot we are about to delete */
1799 if (other_lot == lot)
1800 continue;
1801
1802 lot_list = g_list_prepend (lot_list, other_lot);
1803 }
1804 /* Maintain original split order */
1805 lot_list = g_list_reverse (lot_list);
1806
1807 /* Now remove this link transaction. */
1808 xaccTransClearReadOnly (other_txn);
1809 xaccTransBeginEdit (other_txn);
1810 xaccTransDestroy (other_txn);
1811 xaccTransCommitEdit (other_txn);
1812
1813 /* Re-balance the saved lots as well as is possible */
1814 gncOwnerAutoApplyPaymentsWithLots (&invoice->owner, lot_list);
1815
1816 /* If any of the saved lots has no more splits, then destroy it.
1817 * Otherwise if any has an invoice associated with it,
1818 * send it a modified event to reset its paid status */
1819 for (list_iter = lot_list; list_iter; list_iter = list_iter->next)
1820 {
1821 GNCLot *other_lot = list_iter->data;
1822 GncInvoice *other_invoice = gncInvoiceGetInvoiceFromLot (other_lot);
1823
1824 if (!gnc_lot_count_splits (other_lot))
1825 gnc_lot_destroy (other_lot);
1826 else if (other_invoice)
1827 qof_event_gen (QOF_INSTANCE(other_invoice), QOF_EVENT_MODIFY, NULL);
1828 }
1829 g_list_free (lot_list);
1830 }
1831 g_list_free (lot_split_list);
1832
1833 /* If the lot has no splits, then destroy it */
1834 if (!gnc_lot_count_splits (lot))
1835 gnc_lot_destroy (lot);
1836
1837 /* Clear out the invoice posted information */
1838 gncInvoiceBeginEdit (invoice);
1839
1840 invoice->posted_acc = NULL;
1841 invoice->posted_txn = NULL;
1842 invoice->posted_lot = NULL;
1843 invoice->date_posted = INT64_MAX;
1844
1845 /* if we've been asked to reset the tax tables, then do so */
1846 if (reset_tax_tables)
1847 {
1848 gboolean is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
1849 GList *iter;
1850
1851 for (iter = gncInvoiceGetEntries (invoice); iter; iter = iter->next)
1852 {
1853 GncEntry *entry = iter->data;
1854
1855 gncEntryBeginEdit (entry);
1856 if (is_cust_doc)
1857 gncEntrySetInvTaxTable (entry,
1858 gncTaxTableGetParent (gncEntryGetInvTaxTable( entry)));
1859 else
1860 gncEntrySetBillTaxTable (entry,
1861 gncTaxTableGetParent (gncEntryGetBillTaxTable (entry)));
1862 gncEntryCommitEdit (entry);
1863 }
1864 }
1865
1866 mark_invoice (invoice);
1867 gncInvoiceCommitEdit (invoice);
1868
1869 LEAVE ("TRUE");
1870
1871 return TRUE;
1872}
char xaccTransGetTxnType(Transaction *trans)
Returns the Transaction Type: note this type will be derived from the transaction splits,...
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
#define TXN_TYPE_LINK
Transaction is a link between (invoice and payment) lots
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
SplitList * gnc_lot_get_split_list(const GNCLot *lot)
Returns a list of all the splits in this lot.
Definition gnc-lot.cpp:425
void gncOwnerAttachToLot(const GncOwner *owner, GNCLot *lot)
Attach an owner to a lot.
Definition gncOwner.c:622
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
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...
Definition Split.cpp:1920