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