r21407 - gnucash/trunk/src/engine - Prepare internal post-to code to handle credit notes

Geert Janssens gjanssens at code.gnucash.org
Sun Oct 9 17:06:32 EDT 2011


Author: gjanssens
Date: 2011-10-09 17:06:31 -0400 (Sun, 09 Oct 2011)
New Revision: 21407
Trac: http://svn.gnucash.org/trac/changeset/21407

Modified:
   gnucash/trunk/src/engine/gncInvoice.c
   gnucash/trunk/src/engine/gncInvoice.h
Log:
Prepare internal post-to code to handle credit notes
At the same time clear up some confusing parameter names

Modified: gnucash/trunk/src/engine/gncInvoice.c
===================================================================
--- gnucash/trunk/src/engine/gncInvoice.c	2011-10-09 21:06:23 UTC (rev 21406)
+++ gnucash/trunk/src/engine/gncInvoice.c	2011-10-09 21:06:31 UTC (rev 21407)
@@ -778,7 +778,7 @@
 
 GncOwnerType gncInvoiceGetOwnerType (GncInvoice *invoice)
 {
-    GncOwner *owner;
+    const GncOwner *owner;
     g_return_val_if_fail (invoice, GNC_OWNER_NONE);
 
     owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
@@ -1154,10 +1154,28 @@
     return gncInvoiceLookup(book, guid);
 }
 
+gboolean gncInvoiceAmountPositive (GncInvoice *invoice)
+{
+    switch (gncInvoiceGetType (invoice))
+    {
+        case GNC_INVOICE_CUST_INVOICE:
+        case GNC_INVOICE_VEND_CREDIT_NOTE:
+        case GNC_INVOICE_EMPL_CREDIT_NOTE:
+            return TRUE;
+        case GNC_INVOICE_CUST_CREDIT_NOTE:
+        case GNC_INVOICE_VEND_INVOICE:
+        case GNC_INVOICE_EMPL_INVOICE:
+        case GNC_INVOICE_UNDEFINED:
+            return FALSE;
+        default:
+            return FALSE;
+    }
+}
+
 struct lotmatch
 {
     GncOwner *owner;
-    gboolean reverse;
+    gboolean positive_balance;
 };
 
 static gboolean
@@ -1168,7 +1186,7 @@
     gnc_numeric balance = gnc_lot_get_balance (lot);
 
     /* Is this a payment lot */
-    if (gnc_numeric_positive_p (lm->reverse ? balance :
+    if (gnc_numeric_positive_p (lm->positive_balance ? balance :
                                 gnc_numeric_neg (balance)))
         return FALSE;
 
@@ -1194,7 +1212,8 @@
     GList *iter;
     GList *splitinfo = NULL;
     gnc_numeric total;
-    gboolean reverse;
+    gboolean positive_balance;
+    gboolean is_cust_doc;
     const char *name, *type;
     char *lot_title;
     Account *ccard_acct = NULL;
@@ -1210,9 +1229,14 @@
         gncInvoiceSetTerms (invoice,
                             gncBillTermReturnChild (invoice->terms, TRUE));
 
-    /* Figure out if we need to "reverse" the numbers. */
-    reverse = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
+    /* Does the invoice/credit note have a positive effect on the balance ? Note that
+     * payments for such invoices by definition then have a negative effect on the balance.
+     * This is used to determine which open lots can be considered when posting the invoice. */
+    positive_balance = gncInvoiceAmountPositive (invoice);
 
+    /* GncEntry functions need to know if the invoice/credit note is for a customer or a vendor/employee. */
+    is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
+
     /* Figure out if we need to separate out "credit-card" items */
     owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
     if (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_EMPLOYEE)
@@ -1223,7 +1247,7 @@
         LotList *lot_list;
         struct lotmatch lm;
 
-        lm.reverse = reverse;
+        lm.positive_balance = positive_balance;
         lm.owner = owner;
 
         lot_list = xaccAccountFindOpenLots (acc, gnc_lot_match_owner_payment,
@@ -1281,7 +1305,7 @@
 
         /* Stabilize the TaxTable in this entry */
         gncEntryBeginEdit (entry);
-        if (reverse)
+        if (is_cust_doc)
             gncEntrySetInvTaxTable
             (entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE));
         else
@@ -1296,10 +1320,10 @@
         gncEntryCommitEdit (entry);
 
         /* Obtain the Entry's Value and TaxValues */
-        gncEntryGetValue (entry, reverse, &value, NULL, &tax, &taxes);
+        gncEntryGetValue (entry, is_cust_doc, &value, NULL, &tax, &taxes);
 
         /* add the value for the account split */
-        this_acc = (reverse ? gncEntryGetInvAccount (entry) :
+        this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
                     gncEntryGetBillAccount (entry));
         if (this_acc)
         {
@@ -1328,9 +1352,19 @@
                     xaccAccountCommitEdit (this_acc);
                     xaccTransAppendSplit (txn, split);
 
+                    /* General note on the split creations below:
+                     * Invoice and bill amounts are always stored as positive values in entries
+                     * So to convert them to proper splits, the amounts may have to be reverted
+                     * to have the proper effect on the account balance.
+                     * Credit notes have the opposite effect of invoices/bills, but their amounts
+                     * are stored as negative values as well. So to convert them into splits
+                     * they can be treated exactly the same as their invoice/bill counter parts.
+                     * The net effect is that the owner type is sufficient to determine whether a
+                     * value has to be reverted when converting an invoice/bill/cn amount to a split.
+                     */
                     if (gnc_commodity_equal(xaccAccountGetCommodity(this_acc), invoice->currency))
                     {
-                        xaccSplitSetBaseValue (split, (reverse ? gnc_numeric_neg (value)
+                        xaccSplitSetBaseValue (split, (is_cust_doc ? gnc_numeric_neg (value)
                                                        : value),
                                                invoice->currency);
                     }
@@ -1350,10 +1384,10 @@
                         else
                         {
                             gnc_numeric converted_amount;
-                            xaccSplitSetValue(split, (reverse ? gnc_numeric_neg(value) : value));
+                            xaccSplitSetValue(split, (is_cust_doc ? gnc_numeric_neg(value) : value));
                             converted_amount = gnc_numeric_div(value, gnc_price_get_value(price), GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP);
                             printf("converting from %f to %f\n", gnc_numeric_to_double(value), gnc_numeric_to_double(converted_amount));
-                            xaccSplitSetAmount(split, reverse ? gnc_numeric_neg(converted_amount) : converted_amount);
+                            xaccSplitSetAmount(split, is_cust_doc ? gnc_numeric_neg(converted_amount) : converted_amount);
                         }
                     }
                 }
@@ -1379,7 +1413,7 @@
                     xaccAccountInsertSplit (ccard_acct, split);
                     xaccAccountCommitEdit (ccard_acct);
                     xaccTransAppendSplit (txn, split);
-                    xaccSplitSetBaseValue (split, (reverse ? value : gnc_numeric_neg (value)),
+                    xaccSplitSetBaseValue (split, (is_cust_doc ? value : gnc_numeric_neg (value)),
                                            invoice->currency);
 
                 }
@@ -1421,7 +1455,7 @@
 
         if (gnc_commodity_equal(xaccAccountGetCommodity(acc_val->account), invoice->currency))
         {
-            xaccSplitSetBaseValue (split, (reverse ? gnc_numeric_neg (acc_val->value)
+            xaccSplitSetBaseValue (split, (is_cust_doc ? gnc_numeric_neg (acc_val->value)
                                            : acc_val->value),
                                    invoice->currency);
         }
@@ -1441,11 +1475,11 @@
             else
             {
                 gnc_numeric converted_amount;
-                xaccSplitSetValue(split, (reverse ? gnc_numeric_neg(acc_val->value) : acc_val->value));
+                xaccSplitSetValue(split, (is_cust_doc ? gnc_numeric_neg(acc_val->value) : acc_val->value));
                 converted_amount = gnc_numeric_div(acc_val->value, gnc_price_get_value(price), GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP);
                 printf("converting from %f to %f\n", gnc_numeric_to_double(acc_val->value), gnc_numeric_to_double(converted_amount));
 
-                xaccSplitSetAmount(split, reverse ? gnc_numeric_neg(converted_amount) : converted_amount);
+                xaccSplitSetAmount(split, is_cust_doc ? gnc_numeric_neg(converted_amount) : converted_amount);
             }
         }
     }
@@ -1465,7 +1499,7 @@
         xaccAccountInsertSplit (ccard_acct, split);
         xaccAccountCommitEdit (ccard_acct);
         xaccTransAppendSplit (txn, split);
-        xaccSplitSetBaseValue (split, (reverse ? invoice->to_charge_amount :
+        xaccSplitSetBaseValue (split, (is_cust_doc ? invoice->to_charge_amount :
                                        gnc_numeric_neg(invoice->to_charge_amount)),
                                invoice->currency);
 
@@ -1473,7 +1507,7 @@
                                  GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
     }
 
-    /* Now create the Posted split (which is negative -- it's a credit) */
+    /* Now create the Posted split (which is the opposite sign of the above splits) */
     {
         Split *split = xaccMallocSplit (book);
 
@@ -1485,7 +1519,7 @@
         xaccAccountInsertSplit (acc, split);
         xaccAccountCommitEdit (acc);
         xaccTransAppendSplit (txn, split);
-        xaccSplitSetBaseValue (split, (reverse ? total : gnc_numeric_neg (total)),
+        xaccSplitSetBaseValue (split, (is_cust_doc ? total : gnc_numeric_neg (total)),
                                invoice->currency);
 
         /* add this split to the lot */
@@ -1513,8 +1547,8 @@
      */
     total = gnc_lot_get_balance (lot);
 
-    if ( (gnc_numeric_negative_p (total) && reverse) ||
-            (gnc_numeric_positive_p (total) && !reverse) )
+    if ( (gnc_numeric_negative_p (total) && positive_balance) ||
+            (gnc_numeric_positive_p (total) && !positive_balance) )
     {
         Transaction *t2;
         GNCLot *lot2;
@@ -1613,7 +1647,7 @@
     /* if we've been asked to reset the tax tables, then do so */
     if (reset_tax_tables)
     {
-        gboolean reverse = (gncInvoiceGetOwnerType(invoice) == GNC_OWNER_CUSTOMER);
+        gboolean is_cust_doc = (gncInvoiceGetOwnerType(invoice) == GNC_OWNER_CUSTOMER);
         GList *iter;
 
         for (iter = gncInvoiceGetEntries(invoice); iter; iter = iter->next)
@@ -1621,7 +1655,7 @@
             GncEntry *entry = iter->data;
 
             gncEntryBeginEdit(entry);
-            if (reverse)
+            if (is_cust_doc)
                 gncEntrySetInvTaxTable(entry,
                                        gncTaxTableGetParent(gncEntryGetInvTaxTable(entry)));
             else

Modified: gnucash/trunk/src/engine/gncInvoice.h
===================================================================
--- gnucash/trunk/src/engine/gncInvoice.h	2011-10-09 21:06:23 UTC (rev 21406)
+++ gnucash/trunk/src/engine/gncInvoice.h	2011-10-09 21:06:31 UTC (rev 21407)
@@ -137,7 +137,7 @@
 const char * gncInvoiceGetBillingID (const GncInvoice *invoice);
 const char * gncInvoiceGetNotes (const GncInvoice *invoice);
 GncOwnerType gncInvoiceGetOwnerType (GncInvoice *invoice);
-GList * gncInvoiceGetTypeListForOwnerType (GncOwnerType type);
+GList * gncInvoiceGetTypeListForOwnerType (const GncOwnerType type);
 GncInvoiceType gncInvoiceGetType (GncInvoice *invoice);
 const char * gncInvoiceGetTypeString (GncInvoice *invoice);
 gnc_commodity * gncInvoiceGetCurrency (const GncInvoice *invoice);
@@ -162,6 +162,16 @@
 GList * gncInvoiceGetPrices(GncInvoice *invoice);
 GNCPrice * gncInvoiceGetPrice(GncInvoice *invoice, gnc_commodity* commodity);
 
+/** 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.
+ */
+gboolean gncInvoiceAmountPositive (GncInvoice *invoice);
+
 /** 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



More information about the gnucash-changes mailing list