gnucash maint: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Sat Mar 19 08:22:47 EDT 2016


Updated	 via  https://github.com/Gnucash/gnucash/commit/d1e148ef (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0f66e200 (commit)
	from  https://github.com/Gnucash/gnucash/commit/d45886f7 (commit)



commit d1e148ef87ee1ff553a1c4cdb3da884e68c97299
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Sat Mar 19 14:05:25 2016 +0100

    Refuse to void read-only transactions.
    
    Add test case to verify

diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c
index 06b8016..7cc74ea 100644
--- a/src/engine/Transaction.c
+++ b/src/engine/Transaction.c
@@ -2466,6 +2466,14 @@ xaccTransVoid(Transaction *trans, const char *reason)
 
     g_return_if_fail(trans && reason);
 
+    /* Prevent voiding transactions that are already marked
+     * read only, for example generated by the business features.
+     */
+    if (xaccTransGetReadOnly (trans))
+    {
+        PWARN ("Refusing to void a read-only transaction!");
+        return;
+    }
     xaccTransBeginEdit(trans);
     frame = trans->inst.kvp_data;
 
diff --git a/src/engine/test/test-transaction-voiding.c b/src/engine/test/test-transaction-voiding.c
index 74b4c71..0528f81 100644
--- a/src/engine/test/test-transaction-voiding.c
+++ b/src/engine/test/test-transaction-voiding.c
@@ -154,7 +154,7 @@ run_test (void)
 
     if (xaccTransGetVoidStatus(transaction))
     {
-        failure("void status reports trus after restoring transaction");
+        failure("void status reports true after restoring transaction");
     }
 
     if (xaccTransGetVoidReason(transaction))
@@ -188,6 +188,21 @@ run_test (void)
         failure("former value (after restore) should be zero");
     }
 
+    xaccTransSetReadOnly (transaction, "Read-only void test");
+    xaccTransVoid(transaction, reason);
+
+    ts = xaccTransGetVoidTime (transaction);
+
+    if (xaccTransGetVoidStatus(transaction))
+    {
+        failure("void status reports true while read-only transaction can't be voided");
+    }
+
+    if (xaccTransGetVoidReason(transaction))
+    {
+        failure("void reason exists while read-only transaction can't be voided");
+    }
+
     return;
 }
 
diff --git a/src/gnome/gnc-plugin-page-register.c b/src/gnome/gnc-plugin-page-register.c
index c3e0240..8ddce64 100644
--- a/src/gnome/gnc-plugin-page-register.c
+++ b/src/gnome/gnc-plugin-page-register.c
@@ -2954,6 +2954,12 @@ gnc_plugin_page_register_cmd_void_transaction (GtkAction *action,
         gnc_error_dialog(NULL, "%s", _("You cannot void a transaction with reconciled or cleared splits."));
         return;
     }
+    reason = xaccTransGetReadOnly (trans);
+    if (reason)
+    {
+        gnc_error_dialog(NULL, _("This transaction is marked read-only with the comment: '%s'"), reason);
+        return;
+    }
 
     if (!gnc_plugin_page_register_finish_pending(GNC_PLUGIN_PAGE(page)))
         return;

commit 0f66e2000574477ee0a36a0cd5f4710d1da0f442
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Sat Mar 19 13:44:10 2016 +0100

    Bug 754209 - Bills can be posted multiple times from "find bill" search results - follow up
    
    This commit adds code to check & repair that removes the read only status of the bogus transactions so the user can go in the AP/AR account and delete these bad transactions.
    
    Translators: this commit introduces a new translatable string.

diff --git a/src/engine/ScrubBusiness.c b/src/engine/ScrubBusiness.c
index 9bc113d..f93619b 100644
--- a/src/engine/ScrubBusiness.c
+++ b/src/engine/ScrubBusiness.c
@@ -462,6 +462,50 @@ gncScrubBusinessLot (GNCLot *lot)
     return splits_deleted;
 }
 
+void
+gncScrubBusinessSplit (Split *split)
+{
+    const gchar *memo = _("Please delete this transaction. Explanation at http://wiki.gnucash.org/wiki/Business_Features_Issues#Double_Posting");
+    Transaction *txn;
+
+    if (!split) return;
+    ENTER ("(split=%p)", split);
+
+    txn = xaccSplitGetParent (split);
+    if (txn)
+    {
+        gchar txntype = xaccTransGetTxnType (txn);
+        const gchar *read_only = xaccTransGetReadOnly (txn);
+        gboolean is_void = xaccTransGetVoidStatus (txn);
+        GNCLot *lot = xaccSplitGetLot (split);
+
+        /* Look for transactions as a result of double posting an invoice or bill
+         * Refer to https://bugzilla.gnome.org/show_bug.cgi?id=754209
+         * to learn how this could have happened in the past.
+         * Characteristics of such transaction are:
+         * - read only
+         * - not voided (to ensure read only is set by the business functions)
+         * - transaction type is none (should be type invoice for proper post transactions)
+         * - assigned to a lot
+         */
+        if ((txntype == TXN_TYPE_NONE) && read_only && !is_void && lot)
+        {
+            gchar *txn_date = qof_print_date (xaccTransGetDateEntered (txn));
+            xaccTransClearReadOnly (txn);
+            xaccSplitSetMemo (split, memo);
+            gnc_lot_remove_split (lot, split);
+            PWARN("Cleared double post status of transaction \"%s\", dated %s. "
+                  "Please delete transaction and verify balance.",
+                  xaccTransGetDescription (txn),
+                  txn_date);
+            g_free (txn_date);
+        }
+
+    }
+
+    LEAVE ("(split=%p)", split);
+}
+
 /* ============================================================== */
 
 void
@@ -505,20 +549,72 @@ gncScrubBusinessAccountLots (Account *acc)
 
 /* ============================================================== */
 
+void
+gncScrubBusinessAccountSplits (Account *acc)
+{
+    SplitList *splits, *node;
+    gint split_count = 0;
+    gint curr_split_no = 1;
+    const gchar *str;
+
+    if (!acc) return;
+    if (FALSE == xaccAccountIsAPARType (xaccAccountGetType (acc))) return;
+
+    str = xaccAccountGetName(acc);
+    str = str ? str : "(null)";
+
+    ENTER ("(acc=%s)", str);
+    PINFO ("Cleaning up superfluous lot links in account %s \n", str);
+    xaccAccountBeginEdit(acc);
+
+    splits = xaccAccountGetSplitList(acc);
+    split_count = g_list_length (splits);
+    for (node = splits; node; node = node->next)
+    {
+        Split *split = node->data;
+
+        PINFO("Start processing split %d of %d",
+              curr_split_no, split_count);
+
+        if (split)
+            gncScrubBusinessSplit (split);
+
+        PINFO("Finished processing split %d of %d",
+              curr_split_no, split_count);
+        curr_split_no++;
+    }
+    xaccAccountCommitEdit(acc);
+    LEAVE ("(acc=%s)", str);
+}
+
+/* ============================================================== */
+
+void
+gncScrubBusinessAccount (Account *acc)
+{
+    if (!acc) return;
+    if (FALSE == xaccAccountIsAPARType (xaccAccountGetType (acc))) return;
+
+    gncScrubBusinessAccountLots (acc);
+    gncScrubBusinessAccountSplits (acc);
+}
+
+/* ============================================================== */
+
 static void
 lot_scrub_cb (Account *acc, gpointer data)
 {
     if (FALSE == xaccAccountIsAPARType (xaccAccountGetType (acc))) return;
-    gncScrubBusinessAccountLots (acc);
+    gncScrubBusinessAccount (acc);
 }
 
 void
-gncScrubBusinessAccountTreeLots (Account *acc)
+gncScrubBusinessAccountTree (Account *acc)
 {
     if (!acc) return;
 
     gnc_account_foreach_descendant(acc, lot_scrub_cb, NULL);
-    gncScrubBusinessAccountLots (acc);
+    gncScrubBusinessAccount (acc);
 }
 
 /* ========================== END OF FILE  ========================= */
diff --git a/src/engine/ScrubBusiness.h b/src/engine/ScrubBusiness.h
index 59af9f0..cbf31d5 100644
--- a/src/engine/ScrubBusiness.h
+++ b/src/engine/ScrubBusiness.h
@@ -54,6 +54,21 @@
  */
 gboolean gncScrubBusinessLot (GNCLot *lot);
 
+/** The gncScrubBusinessSplit() function will fix all issues found with
+ *    the given split.
+ *
+ *    Currently this function only does one thing: check if the split is
+ *    part of a transaction that was generated as the result of a doubly
+ *    posted invoice/bill/credit note. Refer to
+ *    https://bugzilla.gnome.org/show_bug.cgi?id=754209 to learn how this
+ *    could have happened in the past.
+ *    If such a transaction is found, its read-only status is removed and
+ *    a warning is written to the trace file. Considering the user may
+ *    already have added a correcting transaction we leave it up to the user
+ *    to decide whether to also delete the transaction or not.
+ */
+void gncScrubBusinessSplit (Split *split);
+
 /** The gncScrubBusinessAccountLots() function will call
  *    gncScrubBusinessLot() on each lot in the given account.
  *
@@ -63,15 +78,26 @@ gboolean gncScrubBusinessLot (GNCLot *lot);
  */
 void gncScrubBusinessAccountLots (Account *acc);
 
+/** The gncScrubBusinessAccountSplits() function will call
+ *    gncScrubBusinessSplit() on each split in the given account.
+ */
+void gncScrubBusinessAccountSplits (Account *acc);
+
+/** The gncScrubBusinessAccount() function will call
+ *    all scrub functions relevant for a given account
+ *    on condition the account is a business related account
+ *    (Accounts Receivable or Accounts Payable type).
+ *
+ *    This routine is the primary routine for fixing all
+ *    (known) issues in a business account.
+ */
+void gncScrubBusinessAccount (Account *acc);
+
 /** The gncScrubBusinessAccountTreeLots() function will call
- *    gncScrubBusinessAccountLots() on each lot in the given account
+ *    gncScrubBusinessAccount() on the given account
  *    and its sub accounts.
- *
- *    This routine is the primary routine for ensuring that the
- *    lot structure of every lot of a business account is in good
- *    order.
  */
-void gncScrubBusinessAccountTreeLots (Account *acc);
+void gncScrubBusinessAccountTree (Account *acc);
 
 /** @} */
 #endif /* GNC_SCRUBBUSINESS_H */
diff --git a/src/gnome/gnc-plugin-page-account-tree.c b/src/gnome/gnc-plugin-page-account-tree.c
index b126eb3..7864e57 100644
--- a/src/gnome/gnc-plugin-page-account-tree.c
+++ b/src/gnome/gnc-plugin-page-account-tree.c
@@ -1573,7 +1573,7 @@ gnc_plugin_page_account_tree_cmd_scrub (GtkAction *action, GncPluginPageAccountT
     if (g_getenv("GNC_AUTO_SCRUB_LOTS") != NULL)
         xaccAccountScrubLots(account);
 
-    gncScrubBusinessAccountLots(account);
+    gncScrubBusinessAccount(account);
 
 
     gnc_resume_gui_refresh ();
@@ -1595,7 +1595,7 @@ gnc_plugin_page_account_tree_cmd_scrub_sub (GtkAction *action, GncPluginPageAcco
     if (g_getenv("GNC_AUTO_SCRUB_LOTS") != NULL)
         xaccAccountTreeScrubLots(account);
 
-    gncScrubBusinessAccountTreeLots(account);
+    gncScrubBusinessAccountTree(account);
 
     gnc_resume_gui_refresh ();
 }
@@ -1613,7 +1613,7 @@ gnc_plugin_page_account_tree_cmd_scrub_all (GtkAction *action, GncPluginPageAcco
     if (g_getenv("GNC_AUTO_SCRUB_LOTS") != NULL)
         xaccAccountTreeScrubLots(root);
 
-    gncScrubBusinessAccountTreeLots(root);
+    gncScrubBusinessAccountTree(root);
 
     gnc_resume_gui_refresh ();
 }
diff --git a/src/gnome/gnc-plugin-page-register.c b/src/gnome/gnc-plugin-page-register.c
index 5ad77b0..c3e0240 100644
--- a/src/gnome/gnc-plugin-page-register.c
+++ b/src/gnome/gnc-plugin-page-register.c
@@ -3726,7 +3726,10 @@ gnc_plugin_page_register_cmd_scrub_current (GtkAction *action,
     split = gnc_split_register_get_current_split (reg);
     lot = xaccSplitGetLot (split);
     if (lot && xaccAccountIsAPARType (xaccAccountGetType (xaccSplitGetAccount (split))))
+    {
         gncScrubBusinessLot (lot);
+        gncScrubBusinessSplit (split);
+    }
     gnc_resume_gui_refresh();
     LEAVE(" ");
 }
@@ -3773,7 +3776,10 @@ gnc_plugin_page_register_cmd_scrub_all (GtkAction *action,
 
         lot = xaccSplitGetLot (split);
         if (lot && xaccAccountIsAPARType (xaccAccountGetType (xaccSplitGetAccount (split))))
+        {
             gncScrubBusinessLot (lot);
+            gncScrubBusinessSplit (split);
+        }
 
         PINFO("Finished processing split %d of %d",
               curr_split_no, split_count);



Summary of changes:
 src/engine/ScrubBusiness.c                 | 102 ++++++++++++++++++++++++++++-
 src/engine/ScrubBusiness.h                 |  38 +++++++++--
 src/engine/Transaction.c                   |   8 +++
 src/engine/test/test-transaction-voiding.c |  17 ++++-
 src/gnome/gnc-plugin-page-account-tree.c   |   6 +-
 src/gnome/gnc-plugin-page-register.c       |  12 ++++
 6 files changed, 170 insertions(+), 13 deletions(-)



More information about the gnucash-changes mailing list