diff --git a/libgnucash/engine/test/utest-Invoice.c b/libgnucash/engine/test/utest-Invoice.c index 65fe389d1f..7a4af807c0 100644 --- a/libgnucash/engine/test/utest-Invoice.c +++ b/libgnucash/engine/test/utest-Invoice.c @@ -25,6 +25,7 @@ #include #include #include "../gncInvoice.h" +#include "../Transaction.h" static const gchar *suitename = "/engine/gncInvoice"; void test_suite_gncInvoice ( void ); @@ -48,7 +49,9 @@ typedef struct gnc_commodity *commodity; GncInvoice* invoice; + GncInvoice* invoice2; Transaction *trans; + Transaction *trans2; } Fixture; static void @@ -66,16 +69,20 @@ setup( Fixture *fixture, gconstpointer pData ) if (data->is_cust_doc) { + xaccAccountSetType (fixture->account2, ACCT_TYPE_RECEIVABLE); fixture->customer = gncCustomerCreate(fixture->book); gncOwnerInitCustomer(&fixture->owner, fixture->customer); } else { + xaccAccountSetType (fixture->account2, ACCT_TYPE_PAYABLE); fixture->vendor = gncVendorCreate(fixture->book); gncOwnerInitVendor(&fixture->owner, fixture->vendor); } fixture->invoice = gncInvoiceCreate(fixture->book); + fixture->invoice2 = NULL; + fixture->trans2 = NULL; } static void @@ -143,12 +150,137 @@ setup_with_invoice( Fixture *fixture, gconstpointer pData ) fixture->trans = gncInvoicePostToAccount(fixture->invoice, fixture->account2, ts1, ts2, "memo", TRUE, FALSE); } + +static void +setup_with_invoice_and_payment (Fixture *fixture, gconstpointer pData) +{ + Split *split; + GNCLot *lot; + gnc_numeric amt = gnc_numeric_create (1000, 100); + + /* 1. create invoice */ + setup_with_invoice (fixture, pData); + + /* 2. create payment */ + fixture->trans2 = xaccMallocTransaction (fixture->book); + lot = gncInvoiceGetPostedLot (fixture->invoice); + + xaccTransBeginEdit (fixture->trans2); + xaccTransSetCurrency (fixture->trans2, fixture->commodity); + + /* This split will balance the invoice lot */ + split = xaccMallocSplit (fixture->book); + xaccSplitSetParent (split, fixture->trans2); + xaccAccountBeginEdit (fixture->account2); + xaccSplitSetAccount (split, fixture->account2); + xaccSplitSetValue (split, gnc_numeric_neg (amt)); + xaccSplitSetAmount (split, gnc_numeric_neg (amt)); + xaccSplitSetLot (split, lot); + + /* bank split will balance the transaction */ + split = xaccMallocSplit (fixture->book); + xaccSplitSetParent (split, fixture->trans2); + xaccAccountBeginEdit (fixture->account); + xaccSplitSetAccount (split, fixture->account); + xaccSplitSetValue (split, amt); + xaccSplitSetAmount (split, amt); + + xaccTransCommitEdit (fixture->trans2); + xaccAccountCommitEdit (fixture->account); + xaccAccountCommitEdit (fixture->account2); + + gncInvoiceAutoApplyPayments (fixture->invoice); +} + +static void +setup_with_invoice_and_CN (Fixture *fixture, gconstpointer pData) +{ + const InvoiceData *data = (InvoiceData*) pData; + + time64 ts1 = gnc_time(NULL); + time64 ts2 = ts1; + const char *desc = "Test description"; + GncEntry *entry = NULL; + Split *split; + GNCLot *lot1, *lot2; + gnc_numeric amt = gnc_numeric_create (1000, 100); + + setup (fixture, pData); + + /* 1. invoice */ + fixture->invoice = gncInvoiceCreate (fixture->book); + gncInvoiceSetCurrency (fixture->invoice, fixture->commodity); + gncInvoiceSetOwner (fixture->invoice, &fixture->owner); + + entry = gncEntryCreate(fixture->book); + gncEntrySetDate (entry, ts1); + gncEntrySetDateEntered (entry, ts1); + gncEntrySetDescription (entry, desc); + gncEntrySetDocQuantity (entry, amt, FALSE); + gncEntrySetBillAccount (entry, fixture->account); + gncBillAddEntry (fixture->invoice, entry); + + gncInvoicePostToAccount (fixture->invoice, fixture->account2, ts1, ts2, "memo", TRUE, FALSE); + + /* 2. CN */ + fixture->invoice2 = gncInvoiceCreate (fixture->book); + gncInvoiceSetCurrency (fixture->invoice2, fixture->commodity); + gncInvoiceSetOwner (fixture->invoice2, &fixture->owner); + + entry = gncEntryCreate(fixture->book); + gncEntrySetDate (entry, ts1); + gncEntrySetDateEntered (entry, ts1); + gncEntrySetDescription (entry, desc); + gncEntrySetDocQuantity (entry, amt, TRUE); + gncEntrySetInvAccount(entry, fixture->account); + gncInvoiceAddEntry (fixture->invoice2, entry); + + gncInvoicePostToAccount (fixture->invoice2, fixture->account2, ts1, ts2, "memo", TRUE, FALSE); + + /* 3. now create the LL txn linking Invoice and CN */ + lot1 = gncInvoiceGetPostedLot (fixture->invoice); + lot2 = gncInvoiceGetPostedLot (fixture->invoice2); + fixture->trans2 = xaccMallocTransaction (fixture->book); + + xaccTransBeginEdit (fixture->trans2); + xaccTransSetCurrency (fixture->trans2, fixture->commodity); + xaccAccountBeginEdit (fixture->account2); + + /* This split will balance the invoice */ + split = xaccMallocSplit (fixture->book); + xaccSplitSetParent (split, fixture->trans2); + xaccSplitSetAccount (split, fixture->account2); + xaccSplitSetValue (split, gnc_numeric_neg (amt)); + xaccSplitSetAmount (split, gnc_numeric_neg (amt)); + xaccSplitSetLot (split, lot1); + + /* This split will balance the CN*/ + split = xaccMallocSplit (fixture->book); + xaccSplitSetParent (split, fixture->trans2); + xaccSplitSetAccount (split, fixture->account2); + xaccSplitSetValue (split, amt); + xaccSplitSetAmount (split, amt); + xaccSplitSetLot (split, lot2); + + xaccTransCommitEdit (fixture->trans2); + xaccAccountCommitEdit (fixture->account2); +} + static void teardown_with_invoice( Fixture *fixture, gconstpointer pData ) { + if (fixture->trans2) + xaccTransDestroy (fixture->trans2); + gncInvoiceUnpost(fixture->invoice, TRUE); gncInvoiceRemoveEntries (fixture->invoice); + if (fixture->invoice2) + { + gncInvoiceUnpost(fixture->invoice2, TRUE); + gncInvoiceRemoveEntries (fixture->invoice2); + } + teardown(fixture, pData); } @@ -230,6 +362,25 @@ test_invoice_posted_trans ( Fixture *fixture, gconstpointer pData ) } } +// Testing for TXN_TYPE_INVOICE TXN_TYPE_PAYMENT are strictly testing functions +// in Transaction.c, but require creating invoices, so, they are tested in +// this file instead. +static void +test_xaccTransGetTxnTypeInvoice (Fixture *fixture, gconstpointer pData) +{ + g_assert_cmpint (TXN_TYPE_INVOICE, ==, xaccTransGetTxnType (fixture->trans)); + + g_assert_cmpint (TXN_TYPE_PAYMENT, ==, xaccTransGetTxnType (fixture->trans2)); +} + + +static void +test_xaccTransGetTxnTypeLink (Fixture *fixture, gconstpointer pData) +{ + g_assert_cmpint (TXN_TYPE_LINK, ==, xaccTransGetTxnType (fixture->trans2)); +} + + void test_suite_gncInvoice ( void ) { @@ -244,4 +395,8 @@ test_suite_gncInvoice ( void ) GNC_TEST_ADD( suitename, "post trans - customer creditnote", Fixture, &pData, setup_with_invoice, test_invoice_posted_trans, teardown_with_invoice ); pData.is_cn = FALSE; // Customer invoice GNC_TEST_ADD( suitename, "post trans - customer invoice", Fixture, &pData, setup_with_invoice, test_invoice_posted_trans, teardown_with_invoice ); + + /* test txn type heuristics */ + GNC_TEST_ADD( suitename, "tests txntype I & P", Fixture, &pData, setup_with_invoice_and_payment, test_xaccTransGetTxnTypeInvoice, teardown_with_invoice); + GNC_TEST_ADD( suitename, "tests txntype L", Fixture, &pData, setup_with_invoice_and_CN, test_xaccTransGetTxnTypeLink, teardown_with_invoice); } diff --git a/libgnucash/engine/test/utest-Transaction.cpp b/libgnucash/engine/test/utest-Transaction.cpp index c9bbf0f0c1..878b5b6bcd 100644 --- a/libgnucash/engine/test/utest-Transaction.cpp +++ b/libgnucash/engine/test/utest-Transaction.cpp @@ -1838,6 +1838,10 @@ test_xaccTransGetReadOnly (Fixture *fixture, gconstpointer pData) static void test_xaccTransGetTxnType (Fixture *fixture, gconstpointer pData) { + // note this will only test TXN_TYPE_NONE, because TxnType is derived + // from split data. Testing for TXN_TYPE_INVOICE TXN_TYPE_PAYMENT + // will require creating invoices, so, they are tested in + // utest-Invoice.c auto txn = fixture->txn; g_assert_cmpint (TXN_TYPE_NONE, ==, xaccTransGetTxnType(txn)); }